在Hibernate中提供了两种缓存来提升程序的性能,分别为一级缓存和二级缓存,也称为内置缓存和外置缓存。
一级缓存在Session中实现,当Session关闭时一级缓存就失效了。我们来看一个使用了来一级缓存的示例:
Session session = factory.openSession(); Student stu = (Student) session.get(Student.class, 21L); Student stu2 = (Student) session.get(Student.class, 21L); session.close();
我们在同一个Session中使用get方法获取同一个对象两次,当代码运行时,控制台只输出一条SQL语句,这就证明了一级缓存的作用,通过Session对象的contains方法来判断一个对象是否在一级缓存中。
Session session = factory.openSession(); Student stu = (Student) session.get(Student.class, 21L); System.out.println(session.contains(stu)); Student stu2 = (Student) session.get(Student.class, 21L); System.out.println(session.contains(stu2)); session.close();
在Session中还提供了clear方法,用于将一级缓存中的所有对象进行清除。使用evict方法将指定的对象从一级缓存中清除。
SessionFactory factory = config.buildSessionFactory(); Session session = factory.openSession(); Student stu = (Student) session.get(Student.class, 21L); session.evict(stu); //将stu从一级缓存中清除 Student stu2 = (Student) session.get(Student.class, 21L); session.close();
上面的代码中由于将stu从一级缓存中清除,所以在控制台中会产生两条SQL语句。一级缓存由Hibernate来进行维护,一般不需要我们使用手工干预。
在Hibernate中二级缓存在SessionFactory中实现,由一个SessionFactory的所有Session实例所共享。Session在查找一个对象时,会首先在自己的一级缓存中进行查找,如果没有找到,则进入二级缓存中进行查找,如果二级缓存中存在,则将对象返回,如果二级缓存中也不存在,则从数据库中获得。
Hibernate并未提供对二级缓存的产品化实现,而是为第三方缓存组件的使用提供了接口,当前Hibernate支持的第三方二级缓存的实现如下:
EHCache
OSCache
SwarmCache
JBossTreeCache
在使用二级缓存之前需要进行一些配置(以EHCache为例)。首先将Hibernate开发包中lib目录下的ehcache-1.2.jar放到工程的build Path中。然后在Hibernate的配置文件hibernate.cfg.xml中添加如下配置项:
<property name="hibernate.cache.provider_class"> net.sf.ehcache.hibernate.EhCacheProvider </property>
在工程的classPath中建立EHCache的配置文件ehcache.xml。
<ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" ① eternal="false" ② timeToIdleSeconds="120" ③ timeToLiveSeconds="120" ④ overflowToDisk="true" ⑤ /> </ehcache>
① 缓存中最大允许保存的对象数量。
② 缓存中数据是否为常量。
③ 缓存数据钝化时间,单位为秒。
④ 缓存数据生存时间,单位为秒。
⑤ 内存不足时,是否启用磁盘缓存。
在需要进行二级缓存的持久化对象的映射文件中指定缓存的同步策略。
<hibernate-mapping> <class name="com.zhaolongedu.vo.Student" table="t_student"> <cache usage="read-only"/> ① … </class> </hibernate-mapping>① 指定缓存的同步策略。不同的缓存实现,对缓存的同步策略的支持也是不相同的。EHCache支持以下三种同步策略:
1. read-only:只读。对于不会发生改变的数据,可以使用只读性缓存。
2. read-write:可读写缓存。用于对数据同步要求严格的情况。
3. nonstrict-read-write:如果程序对并发访问下的数据同步要求不是很严格,且数据更新操作不频繁时可采用该缓存策略。
用下面的示例演示二级缓存的作用:
public static void main(String[] args) { Configuration config = new Configuration(); config.configure(); SessionFactory factory = config.buildSessionFactory(); Session session = factory.openSession(); Student stu = (Student) session.get(Student.class, 21L); session.close(); Session session2 = factory.openSession(); Student stu2 = (Student) session2.get(Student.class, 21L); session2.close(); }
程序的运行结果是输出一条SQL语句,说明二级缓存设置生效。SessionFactory对象中的evict用于将指定对象从二级缓存中删除。
Session session = factory.openSession(); Student stu = (Student) session.get(Student.class, 21L); session.close(); factory.evict(Student.class); Session session2 = factory.openSession(); Student stu2 = (Student) session2.get(Student.class, 21L); session2.close();
此时上面的代码执行结果为输出两条SQL语句。