上篇博客简单介绍了hibernate的一级缓存,也就是session级别的缓存,它的生命周期和会话是相同的,不同的会话之间的缓存不能共享。二级缓存也称为进程级的缓存或sessionFactory级的缓存,它可以被所有的会话共享,二级缓存的生命周期和sessionFactory的生命周期一致,sessionFactory可以管理二级缓存。
hibernate没有提供相应的二级缓存的组件,需要加入额外的二级缓存包,hibernate缓存策略的提供主要是EHCache,OSCache,SwarmCache,JBoss TreeCache。常用的是EHcache
一,环境配置
引入ehcache的相应jar包
2. 将ehcache.xml中配置文件拷贝到SRC下
在hibernate.cfg.xml文件中加入ehcache的配置
<property name =“hibernate.cache.provider_class”> org.hibernate.cache.EhCacheProvider </ property>
4.
在hibernate.cfg.xml的文件中启用二级缓存
<propertynamepropertyname =“hibernate.cache.use_second_level_cache”> true </ property>
5.指定哪些实体类型使用二级缓存,可以在映射文件中采用<cache>标签指定或在hibernate.cog.xml文件中指定,下面的代码在hibernate.cfg.xml中进行统一指定。
<class-cacheclassclass-cacheclass =“com.www.hibernate.Student”usage =“read-only”/>
二,测试类
通过测试类来看二级缓存
public class CacheTest extends TestCase {
/ **
*开启二级缓存
*:
*在两个会话中发负载
* /
public void testCache1(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
学生student(学生)session.load(Student.class,10);
System.out.println(“student.name =”+ student.getName());
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
学生student(学生)session.load(Student.class,10);
//不会发出查询语句,因为配置二级缓存,session可以共享二级缓存中的数据
//二级缓存是进程级的缓存
System.out.println(“student.name =”+ student.getName());
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
}}
/ **
*开启二级缓存
*:
*在两个会议中发get
* /
public void testCache2(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
学生student =(Student)session.get(Student.class,10);
System.out.println(“student.name =”+ student.getName());
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
学生student =(Student)session.get(Student.class,10);
//不会发出查询语句,因为配置二级缓存,session可以共享二级缓存中的数据
//二级缓存是进程级的缓存
System.out.println(“student.name =”+ student.getName());
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
}}
/ **
*开启二级缓存
*:
*在两个会话中发送负载查询,采用会话中的sessionFactory管理二级缓存
* /
public void testCache3(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
学生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();
}最后{
HibernateUtils.closeSession(session);
}}
//管理二级缓存
HibernateUtils.getSessionFactory()。evict(Student.class,1);
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
学生student =(Student)session.load(Student.class,1);
//管理二级缓存
//HibernateUtils.getSessionFactory().evict(Student.class);
System.out.println(“student.name =”+ student.getName());
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
}}
/ **
*开启二级缓存
*:
*一级缓存和二级缓存的交互
* /
public void testCache4(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
//禁止将一级缓存中的数据放入二级缓存中
session.setCacheMode(CacheMode.IGNORE);
学生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();
}最后{
HibernateUtils.closeSession(session);
}}
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
学生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();
}最后{
HibernateUtils.closeSession(session);
}}
}}
/ **
*大批量的数据添加,如清洁了一级缓存,二级缓存也会清出
* /
public void testCache7(){
会话session = null;
尝试{
session = HibernateUtils.getSession();
session.beginTransaction();
//禁止一级缓存和二级缓存交互
session.setCacheMode(CacheMode.IGNORE);
for(int i = 0; i <100; i ++){
学生student =新学生();
student.setName(“张三”+ i);
session.save(student);
if(i%20 == 0){
//执行sql语句,相当于把这些缓存全部保存到数据库中
session.flush();
//清楚缓存的内容
session.clear();
}}
}}
session.getTransaction()。commit();
} catch(Exception e){
e.printStackTrace();
session.getTransaction()。rollback();
}最后{
HibernateUtils.closeSession(session);
}}
}}
}}
小结:
上层的代码还是比较清晰的,不想多做解释,,应该可以理解。二级缓存中适合存在很少被修改的数据;不是很重要的数据,允许出现偶尔并发;不被被并发访问的数据。一级和二级的缓存都是缓存实体对象的,而查询缓存是缓存普通属性结果集的,下一博客介绍查询缓存。