1.hibernate一级缓存和快照机制
1.什么是缓存?
就是存在内存中的数据
2.为什么要用缓存?
为了减少与数据库的交互次数,,从而提高查询效率。
3. 什么样的数据适合使用缓存?
一般是经常查询的数据、不会被经常修改的数据
即使查询出的数据与实际结果不符,对业务没有太大的影响的数据。
4.hibernate的一级缓存 - session缓存
session把查询结果放在session缓存中,第二次查询时,session根据OID判断缓存中是否存在要查询的对象,如果存在,则不再查询,而是将缓存数据返回。
public void get() { Session session = HibernateUtils.getOpenSession(); Transaction ts = session.beginTransaction(); User user = session.get(User.class, 1); user.setAge(99); User user2 = session.get(User.class, 1); System.out.println(user == user2); ts.commit(); session.close(); }
5.快照机制
当hibernate查询出对象时,不进放在一级缓存中,还会向快照区域中存放同样的对象【copy,地址不同】。快照区域的对象不能更改的,而一级缓存中的对象是可以更改的。如果一级缓存中的对象更改了,那么当执行commit操作的时候,会执行update操作【当执行commit操作时,一级缓存对象根据OID和快照对象进行对比,如果不一样,进行更新】
2.hibernate中的对象状态
临时状态:没有OID,和session没有关系
持久化状态:有OID,和session有关系,
save之后,对象就会存在OID
托管状态:有OID,和session没有关系。
删除状态:有OID,
saveOrUpdate({id=xx, username=xx, ...}):数据库中没有则执行保存操作,有则执行更新操作。
clear():清楚session缓存
3. hibernate的事务控制
1. session安全控制
- session使用原则:一个线程中只能有一个
- sessionFactory使用原则:一个应用中只能有一个
通过配置文件实现:hibernate.cfg.xml
<!-- 将Session与线程绑定=> 只有配置了该配置,才能使用getCurrentSession --> <property name="hibernate.current_session_context_class">thread</property>
获取session :{thread_id1: session1, thread_id2: session2, ....}
//提供当前线程的session,线程隔离技术ThreadLocal public static Session getCurrentSession(){ Session session = (Session) sf.getCurrentSession(); return session; }
注意:使用getCurrentSession 获取的session不需要自己关闭,否则会报错
end