Hibernate缓存机制学习笔记
来源:互联网 发布:js遍历jsong数组赋值 编辑:程序博客网 时间:2024/06/05 06:51
持久化层的缓存的范围
缓存的范围决定了缓存的生命周期以及可以被谁访问。缓存的范围分为三类:
·事务范围:缓存只能被当前事务访问。缓存的生命周期依赖于事务的生命周期,当事务结束时,缓存也就结束生命周期。
·进程范围:缓存被进程内的所有事务共享。这些事务有可能并发访问缓存,因此必须对缓存采取必要的事务隔离机制。进程范围的缓存可能会存放大量的数据,所以存放的介质可以是内存或硬盘。
·集群范围:在集群环境中,缓存被一个机器或者多个机器的进程共享。缓存中的数据被复制到集群环境中的每个进程节点,进程间通过远程通信来保证缓存中的数据的一致性。
事务范围的缓存是持久化层的第一级缓存,通常它是必需的;进程范围或集群范围的缓存是持久化层的第二级缓存。
Hibernate中的缓存
Hibernate中提供了两级缓存:第一级别的缓存是Session级别的缓存,它是属于事务范围的缓存。这一级别的缓存由Hibernate管理,一般情况下无需进行干预;第二级别的缓存是SessionFactory级别的缓存,它是属于进程范围或集群范围的缓存。
下面的表格展示了第一级缓存与第二级缓存的区别。
一级缓存的管理:
当应用程序调用session的save、update、saveorupdate、get、load以及调用查询接口的list、iterate、filter方法时,如果在session缓存中还不存在相应的对象,Hibernate就会把该对象加入到第一级缓存中。当清理缓存时,Hibernate会根据缓存中对象的状态变化来同步更新数据库。
session为应用程序提供了两个管理缓存的方法:
evict(Object obj):从缓存中清除参数指定的持久化对象
clear():清空缓存中所有持久化对象。
下面是我做过的一个测试session级缓存的例子,Debug的时候可能会看的更清晰一些:
/*** 在同一个session中发出两次load查询
* fkg*/public void testCache1() {Session session = null;try {session = HibernateUtils.getSession();session.beginTransaction();Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());//不会发出查询语句,load使用缓存student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());session.getTransaction().commit();}catch(Exception e) {e.printStackTrace();session.getTransaction().rollback();}finally {HibernateUtils.closeSession(session);}}
二级缓存的管理:
1)条件查询的时候,总是发出sql查询语句到数据库查询,一次获得所有的数据对象
2)把获得的所有数据对象根据ID存放到二级缓存中
3)当Hibernate根据ID访问数据对象的时候,首先从Session一级缓存中查,查不到,如果配置了二级缓存,那么从二级缓存中查,查不到再查询数据库,把结果按照ID放到缓存。
4)删除、更新、增加数据的时候,同时更新缓存。
二级缓存在实现的时候,需要先在Hibernate的配置文件中设置一下:
<!-- 配置缓存提供商 --><property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property><!-- 启用二级缓存,这也是它的默认配置 --><property name="hibernate.cache.use_second_level_cache">true</property><mapping resource="com/bjpowernode/hibernate/Student.hbm.xml"/><mapping resource="com/bjpowernode/hibernate/Classes.hbm.xml"/>
当然也可以指定某个类使用二级缓存:<!-- 指定Student使用二级缓存--><class-cache class="com.bjpowernode.hibernate.Student" usage="read-only"/>
然后编写一个测试类:/*** 开启二级缓存** 在两个session中发load查询*/public void testCache1() {Session session = null;try {session = HibernateUtils.getSession();session.beginTransaction();Student student = (Student)session.load(Student.class, 1);System.out.println("student.name=" + student.getName());session.getTransaction().commit();}catch(Exception e) {e.printStackTrace();session.getTransaction().rollback();}finally {HibernateUtils.closeSession(session);}try {session = HibernateUtils.getSession();session.beginTransaction();Student student = (Student)session.load(Student.class, 1);//不会发出查询语句,因为配置二级缓存,session可以共享二级缓存中的数据//二级缓存是进程级的缓存System.out.println("student.name=" + student.getName());session.getTransaction().commit();}catch(Exception e) {e.printStackTrace();session.getTransaction().rollback();}finally {HibernateUtils.closeSession(session);}}
·什么样的数据适合放到第二级缓存
1)很少被修改的数据
2)不是很重要的数据,允许出现偶尔并发的数据
3)不会被并发访问的数据
4)参考数据。
查询缓存
对于经常适用的查询语句,如果启用了查询缓存,当第一次执行查询语句时,Hibernate会把查询结果放到第二缓存中。以后再次执行该查询语句时,只需从缓存中获得查询结果,从而提高查询性能。
下面是我做的一个小实例:
1)引入ehcache.xml文件放到src文件夹下。
2)编写实体类等
3)测试类:
/*** 开启查询,关闭二级缓存,采用query.list()查询普通属性* * 在一个session中发query.list()查询*/public void testCache1() {Session session = null;try {session = HibernateUtils.getSession();session.beginTransaction();List names = session.createQuery("select s.name from Student s").setCacheable(true).list();for (int i=0; i<names.size(); i++) {String name = (String)names.get(i);System.out.println(name);}System.out.println("-------------------------------------------------------");//不会发出查询语句,因为启用查询缓存names = session.createQuery("select s.name from Student s").setCacheable(true).list();for (int i=0; i<names.size(); i++) {String name = (String)names.get(i);System.out.println(name);}session.getTransaction().commit();}catch(Exception e) {e.printStackTrace();session.getTransaction().rollback();}finally {HibernateUtils.closeSession(session);}}
学习小结
一级缓存是必要的,需要根据实际的业务需要考虑要不要使用二级缓存。对于查询缓存还是第一次以这种形式学习到,希望在实践中继续提升。本文不当之处多多指教哦。小编给大家推荐一篇写的不错的相关博客:http://www.cnblogs.com/wean/archive/2012/05/16/2502724.html- Hibernate缓存机制学习笔记
- hibernate缓存机制(学习笔记)
- Hibernate缓存机制笔记
- Hibernate学习---缓存机制
- Hibernate学习笔记 -- day05 缓存、快照机制、对象状态
- Hibernate缓存学习笔记
- Hibernate缓存学习笔记
- Hibernate学习笔记之缓存
- Hibernate学习笔记----session缓存
- PetShop学习笔记----缓存机制
- MyBatis缓存机制学习笔记
- Android缓存机制学习笔记
- Hibernate学习记录4 缓存机制
- Hibernate学习笔记之----理解对象的持久性与一级缓存机制
- hibernate学习之五(hibernate的缓存机制)
- Hibernate学习笔记-----------缓存的知识
- hibernate学习笔记(session一级缓存)
- Hibernate学习笔记之三种缓存
- Android处理图片OOM的若干方法小结
- (HDU 5763)Another Meaning <KMP + dp> 多校训练4
- Unity3D 如何把Spine动画导入Unity5.4
- mysql存储过程
- Nginx安装及配置
- Hibernate缓存机制学习笔记
- [算法]直线与圆的交点程序设计
- MongoDB在.NET中使用官方驱动的插入操作
- 智商被碾压1.15
- Hrbust 2230 括号子序列-A【dp】感谢Zqc!
- 重复字符串(powerstr)
- linux下的dnw软件的使用
- HTML5&CSS3初学者指南(1) – 编写第一行代码
- OIBH杯第三次普及组模拟赛T1 立体井字棋