您的位置:首页 > 其它

Hibernate缓存

2011-12-16 22:49 225 查看
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("fromUser where id=1").setCacheable(true).list();setCacheable(true)激活查询缓存,然后在Session关闭以后,在执行一条session.createQuery("fromUser 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. />
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: