Hibernate缓存

来源:互联网 发布:php抓取淘宝商品 编辑:程序博客网 时间:2024/06/05 15:04

Hibernate缓存:缓存是在内存中的一块高速区域。

Hibernate缓存的作用:可以把查询出来的数据存储在内存或者磁盘,节省下次同样查询语句再次查询数据库,大幅减轻数据库压力。

在Hibernate中,缓存分为2种方式:

1.一级缓存: Hibernate默认支持的,是属于Session级别的,也就是说跟它跟Session的生命周期息息相关。

2.二级缓存:Hibernate二级缓存是一个可插拔的的缓存插件,它是由SessionFactory负责管理。由于SessionFactory对象的生命周期和应用程序的整个过程对应。

Hibernate的二级缓存策略的一般过程如下:

    1.配置好二级缓存。

    2.如:执行get(User.class,1);然后关闭session,这个时候,同样在执行一次get(User.class,1);这样的语句,它在执行第一次的时候,首先,先将第一次查询到的结果放到一级缓存中,并复制一份放到二级缓存中,然后把id为1作为key放入一个内存中的id列表里面,当第二次执行同样的代码的时候,会先在一级缓存里找,这个时候因为Session已经关闭了,那么就会到二级缓存里面找,先找在id列表里面找id为1的的id列表,很显然会找到,然后会根据这个id在相应的类缓存中找到对应的对象。

在二级缓存中还有一个查询缓存,它只对list起作用,对iterator不起作用。

Hibernate查询缓存 生命周期不固定 ,当数据库 表发生改变的使用Hibernate查询缓存马上消失。

  Hibernate的查询缓存策略的过程如下:

 1.启动查询缓存。

  2.然后执行如:session.createQuery("from User where id=1").setCacheable(true).list();setCacheable(true)激活查询缓存,然后在Session关闭以后,在执行一条session.createQuery("from User where id=1").setCacheable(true).list();这样的语句,第一次执行的时候,会先将第一次查询到的结果放入到一级缓存中,并将该实体的id为key放入到二级缓存中,然后以SQL为key放入的二级缓存的查询缓存中,当第二次执行相同的语句的时候,系统会先在一级缓存中里面找,如果找不到,在到二级缓存中来找,系统会先根据id为因为是HQL语句来查询的所以没有id项,然后就会根据SQL来到二级缓存中的查询缓存里面来找,这次找到了,就返回该实体。

好了,说了那么多,接下来我们来实战一下:

首先是先在Hibernate-cfg.xml里面来配置二级缓存,配置如下:

1.       <!-- 启动二级缓存 -->   

2.       <!-- 打开二级缓存 -->   

3.         <property name="cache.use_second_level_cache">true</property>   

4.       <!-- 设置Hibernate的缓存接口类,也就是选用缓存的组件 -->           

5. <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>  

6.         <!-- 启动查询缓存 -->   

7.         <property name="cache.use_query_cache">true</property>       

8.         <mapping resource="com/lovo/po/User.hbm.xml"/>   

9.         <!-- 要缓存的类 -->   

10.         <class-cache class="com.lovo.po.User" usage="read-write"/>   

这里,我们主要来说下usage的配置项有:

 只读缓存(read-only)

       如果应用程序需要读取一个持久化类的实例,但是并不打算修改它们,可以使用read-only缓存。这是最简单,也是实用性最好的策略。

对于从来不会修改的数据,如参考数据,可以使用这种并发访问策略。

 读/写缓存(read-write)

       如果应用程序需要更新数据,可能read-write缓存比较合适。如果需要序列化事务隔离级别,那么就不能使用这种缓存策略。

对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读这类的并发问题。

 不严格的读/写缓存(nonstrict-read-write)

       如果程序偶尔需要更新数据(也就是说,出现两个事务同时更新同一个条目的现象很不常见),也不需要十分严格的事务隔离,可能适用nonstrict-read-write缓存。

对于极少被修改,并且允许偶尔脏读的数据,可以采用这种并发访问策略。

事务缓存(transactional)

       transactional缓存策略提供了对全事务的缓存,仅仅在受管理环境中使用。它提供了Repeatable Read事务隔离级别。对于经常被读但很少修改的数据,可以采用这种隔离类型,因为它可以防止脏读和不可重复读这类的并发问题。

       在上面所介绍的隔离级别中,事务型并发访问策略的隔离级别最高,然后依次是读/写型和不严格读写型,只读型的隔离级别最低。事务的隔离级别越高,并发性能就越低。

接着,就是在src目录下面加入ehcache.xml这个文件,这个文件可以在Hibernate源码包中找到,具体配置如下:

1.     <diskStore path="D:/Java/temp"/><!-- 如果超出记录数量,将序列化到硬盘上,默认的是java.io.tmpdir -->   

2.     <!--缓存可以存储的总记录量-->   

3.     <!--缓存是否永远不销毁-->         

4.     <!--当缓存闲置时间超过该值,则缓存自动销毁-->   

5.     <!--缓存创建之后,到达该缓存自动销毁-->   

6.     <!--当缓存中的数据达到最大值时,是否把缓存数据写入磁盘-->   

7. <defaultCache   

8.     maxElementsInMemory="1"     

9.     eternal="false"   

10.     timeToIdleSeconds="1200"   

11.     timeToLiveSeconds="1200"   

12.     overflowToDisk="true"   

13.     />   


原创粉丝点击