Hibernate缓存机制
2016-07-03 20:27
246 查看
缓存的机制在减轻数据库压力方面、提高系统性能方面有很大的作用,在一些数据库框架中也不例外,Hibernate也有它自己的缓存机制。在Hibernate中,缓存分为两级,分别是一级缓存和二级缓存,一级缓存指的是Session级别的缓存,二级缓存指的是SessionFactory级别的缓存。
evit(Object obj):是将指定的对象从一级缓存中清除掉,释放对象占用的资源。
clear():清除一级缓存中所有的对象,释放他们占用的资源。
contains():判断某一个对象是否存在一级缓存中。
flush():刷新一级缓存中的对象,使之与数据库保持同步。
一级缓存主要是缓存实体对象,在save()方法执行时,会向session中保存一份。另外,get()和load()加载数据时,如果缓存中存在数据的话,就直接在缓存中取,如果不存在,再去数据库中取。另外,因为一级缓存是缓存实体对象的,所以当save方法执行完之后,如果用hql语句查询对象,那么这个查询也是从session缓存中获取的。
/**
* 在同一个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());
//不会发出查询语句,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);
}
}
EHCache org.hibernate.cache.EhCacheProvider
OSCache org.hibernate.cache.OSCacheProvider
SwarmCache org.hibernate.cache.SwarmCacheProvider
JBossCache org.hibernate.cache.TreeCacheProvider
在使用二级缓存时,是需要在配置文件中配置这些插件的。首先是在hibernate.cfg.xml中配置二级缓存,指定相应实体使用二级缓存,然后配置二级缓存的配置文件,这样就可以使用二级缓存了。
<!-- 配置缓存提供商 -->
<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"/> 缓存的策略
二级缓存也有几个方法来管理:
evict(Class arg0, Serializable arg1):将某个类指定ID的持久化对象从二级缓存中清除,释放其占用的资源。
evict(Class arg0):将指定类的所有持久化对象都从二级缓存中清除,释放其占用的资源。
evictCollection(String arg0):将指定类的所有持久化对象的集合从二级缓存中清除,释放其占用的资源。
二级缓存没有特定的储存位置,是根据配置文件中配置的位置来缓存的。
如何判断数据是从缓存中读取,还是从数据库中读取呢?可以通过是否发SQL语句来判断。在hibernate.cfg.xml中配置showsql的属性为true,这样在执行数据库操作时就会发出SQL语句。如果是操作的数据库,那么就会发出相应的语句,如果是操作的缓存,那么就不会发出SQL语句。
一级缓存
一级缓存是Session级别的缓存,是存在于Session中的缓存,也称为事务级缓存。它存在的时间比较短,会随着事务的提交,Session的消失而消失。一级缓存是保存在内存中的,跟其持久化对象相关联。一级缓存是调用Session接口是启动的,它是不会过期的,除非清理缓存或者清理相应的持久化对象。一级缓存有几个方法来管理:evit(Object obj):是将指定的对象从一级缓存中清除掉,释放对象占用的资源。
clear():清除一级缓存中所有的对象,释放他们占用的资源。
contains():判断某一个对象是否存在一级缓存中。
flush():刷新一级缓存中的对象,使之与数据库保持同步。
一级缓存主要是缓存实体对象,在save()方法执行时,会向session中保存一份。另外,get()和load()加载数据时,如果缓存中存在数据的话,就直接在缓存中取,如果不存在,再去数据库中取。另外,因为一级缓存是缓存实体对象的,所以当save方法执行完之后,如果用hql语句查询对象,那么这个查询也是从session缓存中获取的。
/**
* 在同一个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());
//不会发出查询语句,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);
}
}
/** * 在同一个session中先调用save,再调用load查询刚刚save的数据 */ public void testCache6() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Student student = new Student(); student.setName("张三"); Serializable id = session.save(student); student = (Student)session.load(Student.class, id); //不会发出查询语句,因为save支持缓存 System.out.println("student.name=" + student.getName()); session.getTransaction().commit(); }catch(Exception e) { e.printStackTrace(); session.getTransaction().rollback(); }finally { HibernateUtils.closeSession(session); } }
/** * 在同一个session中发出两次get查询 */ public void testCache2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Student student = (Student)session.get(Student.class, 1); System.out.println("student.name=" + student.getName()); //不会发出查询语句,get使用缓存 student = (Student)session.get(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); } }
二级缓存
二级缓存是SessionFactory范围内的缓存,它缓存的数据是供一个SessionFactory中的所有Session共享的。二级缓存通常是使用插件来完成的,常用的插件有以下几种:EHCache org.hibernate.cache.EhCacheProvider
OSCache org.hibernate.cache.OSCacheProvider
SwarmCache org.hibernate.cache.SwarmCacheProvider
JBossCache org.hibernate.cache.TreeCacheProvider
在使用二级缓存时,是需要在配置文件中配置这些插件的。首先是在hibernate.cfg.xml中配置二级缓存,指定相应实体使用二级缓存,然后配置二级缓存的配置文件,这样就可以使用二级缓存了。
<!-- 配置缓存提供商 -->
<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"/> 缓存的策略
<ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" 最多缓存对象的个数 eternal="false" 缓存中的对象是否是永远不变的 timeToIdleSeconds="120" 可以操作对象的时间 timeToLiveSeconds="120" 缓存中对象的生命周期 overflowToDisk="true" 内存满了之后,是否缓存到硬盘上 /> <cache name="com.bjpowernode.hibernate.Student" maxElementsInMemory="100" eternal="false" timeToIdleSeconds="10000" timeToLiveSeconds="10000" overflowToDisk="true" /> </ehcache>
/** * 开启二级缓存 * * 在两个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); } } /** * 开启二级缓存 * * 在两个session中发get查询 */ public void testCache2() { Session session = null; try { session = HibernateUtils.getSession(); session.beginTransaction(); Student student = (Student)session.get(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.get(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); } }
二级缓存也有几个方法来管理:
evict(Class arg0, Serializable arg1):将某个类指定ID的持久化对象从二级缓存中清除,释放其占用的资源。
evict(Class arg0):将指定类的所有持久化对象都从二级缓存中清除,释放其占用的资源。
evictCollection(String arg0):将指定类的所有持久化对象的集合从二级缓存中清除,释放其占用的资源。
二级缓存没有特定的储存位置,是根据配置文件中配置的位置来缓存的。
如何判断数据是从缓存中读取,还是从数据库中读取呢?可以通过是否发SQL语句来判断。在hibernate.cfg.xml中配置showsql的属性为true,这样在执行数据库操作时就会发出SQL语句。如果是操作的数据库,那么就会发出相应的语句,如果是操作的缓存,那么就不会发出SQL语句。
总结
在一级缓存和二级缓存都启用的情况下,首先对实体的操作会缓存在一级缓存中,同时也会缓存在二级缓存中一份。当再次操作数据时,先查看需要操作的对象是否在一级缓存中,如果有则直接读取;如果没有则查看是否在二级缓存中,如果有则直接读取,如果没有则操作数据库,这时就要发出SQL语句。一级缓存是缓存在内存中的,它的缓存的对象是没有生命周期的;二级缓存是根据配置文件配置的,同样在配置文件中可以配置缓存对象的缓存时间。一级缓存和二级缓存在对数据库减压方面都有很大的作用,同时也要注意缓存数据的更新问题和并发问题。相关文章推荐
- GetChar缓存机制深入剖析
- Hibernate Oracle sequence的使用技巧
- jsp Hibernate批量更新和批量删除处理代码
- jsp hibernate的分页代码第1/3页
- Struts2+Hibernate实现数据分页的方法
- Hibernate环境搭建与配置方法(Hello world配置文件版)
- JAVA+Hibernate 无限级分类
- SSH整合中 hibernate托管给Spring得到SessionFactory
- jsp hibernate 数据保存操作的原理
- hibernate中的增删改查实现代码
- 解决hibernate+mysql写入数据库乱码
- java优化hibernate性能的几点建议
- java Hibernate延迟加载
- hibernate 常用方法介绍
- 详解Java的Hibernate框架中的注解与缓存
- 浅析Java的Hibernate框架中的继承关系设计
- Hibernate实现批量添加数据的方法
- Hibernate4在MySQL5.1以上版本创建表出错 type=InnDB
- JQuery+Ajax+Struts2+Hibernate框架整合实现完整的登录注册
- SSH框架网上商城项目第16战之Hibernate二级缓存处理首页热门显示