hibernate的缓存机制

提示:缓存主要是用来提高性能,减少数据库的访问频率,主要用来查询,针对很少改变数据的表,因为如果经常改变表结构或数据,就会导致缓存中的数据跟数据库中的数据不一致,出现脏数据。

1.一级缓存

(1)一级缓存是session级别的缓存,当事务提交或回滚时,session就关闭了,它生命周期就结束了。

(2)作用范围很小,仅限于该session之中,其它的session无法访问,相当于线程级别的缓存;

(3)save,update,saveOrUpdate,load,get,list,iterate,lock等方法都将对象放入一级缓存中,一级缓存不能控制缓存的数(据)量,所以要注意大批量操作数据时可能造成内存溢出,可用evict(清除一条记录),clear(清除缓存)方法清除缓存内容,清除钱需要调用flush函数将缓存的数据更新到数据库;

(4)使用iterater时注意:

iterater查询在没有缓存的情况下会有N+1的问题。

执行上面代码查看控制台的sql语句,第一次iterate查询会发出N+1条sql语句,第一条sql语句查询所有的id,然后根据id查询实体对象,有N个id就发出N条语句查询实体。

第二次iterate查询,却只发一条sql语句,查询所有的id,然后根据id到缓存里取实体对象,不再发sql语句到数据库里查询了。

(5)一级缓存只能存放对象,不能存放对象的属性;

2. 二级缓存

(1)二级缓存是sessionFactory级别的缓存,不同session可以访问二级缓存的数据,当然,它也是存放对象的,不存放对象属性

(2)二级缓存必须让sessionfactory管理,让sessionfactory来清除二级缓存。sessionFactory.evict(Student.class);//清除二级缓存中所有student对象,sessionFactory.evict(Student.class,1);//清除二级缓存中id为1的student对象。

(3) Hibernate的二级缓存的实现原理与一级缓存是一样的,也是通过以ID为key的Map来实现对对象的缓存。

(4)二级缓存的适用范围

       Hibernate的二级缓存作为一个可插入的组件在使用的时候也是可以进行配置的,但并不是所有的对象都适合放在二级缓存中。
       在通常情况下会将具有以下特征的数据放入到二级缓存中:
●   很少被修改的数据。
●   不是很重要的数据,允许出现偶尔并发的数据。
●   不会被并发访问的数据。
●   参考数据。
       而对于具有以下特征的数据则不适合放在二级缓存中:
●   经常被修改的数据。
●   财务数据,绝对不允许出现并发。
●   与其他应用共享的数据。
       在这里特别要注意的是对放入缓存中的数据不能有第三方的应用对数据进行更改(其中也包括在自己程序中使用其他方式进行数据的修改,例如,JDBC),因为那样Hibernate将不会知道数据已经被修改,也就无法保证缓存中的数据与数据库中数据的一致性。
 
3. 我们再来讨论一下Session和SessionFactory:
(1)Session是非线程安全的类,不能多个线程同时访问同一个session,session内部相当于封装了一个connection,如果多个线程通过一个连接访问数据库,你可以想像会出现什么情况,session的生命周期很短,一个session代表一个与数据库的连接,在B/S系统中一般不会超过一个请求,对于封装其中的connection,我们一般遵循“尽量晚的获得,尽量早的释放”的原则,如果session长时间打开,内部维护一级缓存和数据库连接,长时间占用内存和数据库连接,对系统的并发的影响会很大的,所以千万不要把session放到HTTPSession中去,它的生命周期就会很长,负载也相当大;
(2)SessionFactory是一个线程安全的类,从名字就可以知道,它是采用了工厂模式的会话工厂类,生命周期很长,它是跟数据库对应的,有多少个库,就有多少个SessionFactory,在服务器启动时就会对它初始化,以后就不再修改了,在系统运行时,SessionFactory会保存所有配置和映射的信息,也可以说通过它都可以找得到;
posted @ 2014-03-26 13:51  java后端领域  阅读(142)  评论(0)    收藏  举报