Hibernate本身只提供了二级缓存的规范,但并未实现,所以需要第三方缓存插件的支持。常用的二级缓存第三方插件有:EHCache、Memcached、OSCache、SwarmCache、JBossCache。这些插件的功能的侧重均有所不同。下面一图说明了插件的在实际应用中的区别:
本例采用EHCache插件。
1、首先,导入需要EHCache插件相关的Jar包。(可通过Hibernate框架的lib\optional\ehcache目录中找到)
2、修改主配置文件hibernate.cfg.xml:
需要开启二级缓以及注册二级缓存工厂,在hibernate.cfg.xml文件中<session-factory>标签中加入以下代码:
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 注册二级缓存区工厂 -->
<property name="hibernate.cache.region.factory_class"><!--需要name可在/project/etc目录中的hibernate.properties查找 -->
org.hibernate.cache.ehcache.EhCacheRegionFactory
</property>
3、添加配置文件ehcache.xml 。
解压ehcache-core-2.4.3.jar
找到ehcacha-failsafe.xml,将其复制到项目中的src目录中,并改名为ehcache.xml
4、再次修改在主配置文件(hibernate.cfg.xml),在主配置文件中指定缓存内容 。
在<mapping/>标签的后面(同样是在<session-factory>标签中)指定类缓存与集合缓存,代码如下:
<!-- 指定类缓存 -->
<class-cache usage="read-only" class="com.beans.Country"/>
<class-cache usage="read-only" class="com.beans.Minister"/>
<!-- 指定集合缓存 -->
<collection-cache usage="read-only" collection="com.beans.Country.ministers"/>
5、以1:n的Country与Minister关联关系为例,演示二级缓存实例。首先,需要插入相关数据,在测试类中写插入数据的方法。
MyTest.java:
@Test
public void test02() {
Session session = HbnUtils.getSession();
try {
session.getTransaction().begin();
Minister minister1 = new Minister("aaa");
Minister minister2 = new Minister("bbb");
Minister minister3 = new Minister("bbb");
Country country = new Country("America");
//Country维护关联关系
country.getMinisters().add(minister1);
country.getMinisters().add(minister2);
country.getMinisters().add(minister3);
session.save(country);
session.getTransaction().commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
session.getTransaction().rollback();
}
}
6、证明二级缓存的存在。为了证明二级缓存的存在,我这里是对插入的数据进行同样的3次查询。接着上例在MyTest.java中加入测试二级缓存的方法。
MyTest.java:
@Test
public void test03() {
Session session = HbnUtils.getSession();
try {
session.beginTransaction();
//第一次查询,将id为1的country对象加载到一级缓存session将引发查询(select语句)
Country country1 = session.get(Country.class, 1);
System.out.println("第一次查询:Cname=" + country1.getCname());
//第二次查询:从session(一级缓存)中直接读取到的id为1的Country对象,不会到数据库中查询,不引发查询
Country country2 = session.get(Country.class, 1);
System.out.println("第二次查询:Cname=" + country2.getCname());
//将一级缓存数据清空,session中Country对象也不存在了
session.clear();
//第三次查询,从二级缓存中读取id为1 的Country对象,不会到数据库中查询,不引发查询
Country country3 = session.get(Country.class, 1);
System.out.println("第三次查询:Cname=" + country3.getCname());
session.getTransaction().commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
session.getTransaction().rollback();
}
}
执行测试方法后,控制台显示如下结果:
明显可以看出,查询只引发了一次,并且是第一次查询所引发的。在第二次查询时,读取的是一级缓存session中的数据,所以不引发。当一级缓存数据被清空后,再次查询也是没有引发的,也就是说第三次查询是从二级缓存中获取的数据,也就证明是二级缓存的存在。
原文地址:https://www.cnblogs.com/qikeyishu/p/9203217.html