Hibernate4配置Ehcache二级缓存
本文参照http://ehcache.org/documentation/integrations/hibernate
本文代码github地址:https://github.com/ayhero/Hibernate-Cache.git
1.添加相关jar包
使用marven引入依赖:
<!-- ehcache缓存 --> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.4.3</version> </dependency> <!--hibernate-ehcache插件--> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>4.2.0.Final</version> </dependency>
2.配置hibernate文件
2.1使用hibernate-cfg.xml
<property name="hibernate.cache.use_second_level_cache">true</property> <property name="hibernate.cache.use_query_cache">true</property> <!--hibernate4--> <property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property> <!--其他版本的hibernate--> <property name="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</property>
2.2使用spring管理Hibernate
<!-- 开启二级缓存 --> <prop key="hibernate.cache.use_second_level_cache">true</prop> <prop key="hibernate.cache.use_query_cache">true</prop> <!--Hibernate 4--> <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop> <!--其他版本的Hibernate--> <prop key="hibernate.cache.region.factory_class">net.sf.ehcache.hibernate.EhCacheRegionFactory</prop>
3.编辑ehcache.xml配置文件
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <diskStore path="user.home/web_ehcache/" /> <defaultCache maxElementsInMemory="3000" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="3600" overflowToDisk="true" diskPersistent="false" diskExpiryThreadIntervalSeconds="100" memoryStoreEvictionPolicy="LRU" /> <!--hibernate允许同一查询使用两个缓存,default为默认缓存,query为自定义缓存,query会覆盖default中重复的配置,不重复部分以各自为准。 缓存区域的名字可以使用以下几个: 1.类的全限定名:如com.entity.User 2.类中的集合属性名:如com.entity.User.roles 3.全局配置:如org.hibernate.cache.StandardQueryCache,org.hibernate.cache.UpdateTimestampsCache,query.AdministrativeAreasPerCountry 4.自定义命名 --> <cache name="query" maxElementsInMemory="3000" eternal="true" overflowToDisk="true" timeToIdleSeconds="36000" timeToLiveSeconds="36000" memoryStoreEvictionPolicy="LFU" /> </ehcache>
4.配置实体类
/* * 使用二级缓存 */ @Cache(region="query",usage=CacheConcurrencyStrategy.READ_WRITE) public class Resc { ...... //集合缓存注解 @Cache(region="query",usage=CacheConcurrencyStrategy.READ_WRITE) private Set<Role> roles; ......
5.测试
Session session1=sessionFactory.openSession(); //事务1 Transaction tx1=session1.beginTransaction(); Resc rs1=(Resc) session1.load(Resc.class, Long.valueOf(1)); System.out.println("rs.getRes_string:"+rs1.getRes_string()); tx1.commit(); session1.close(); //事务2 Session session2=sessionFactory.openSession(); Transaction tx2=session2.beginTransaction(); Resc rs2=(Resc) session2.load(Resc.class, Long.valueOf(1)); System.out.println("rs.getRes_string:"+rs2.getRes_string()); tx2.commit(); session2.close();
6.测试结果
第一次查询,存入缓存
Hibernate: select resc0_.id as id1_0_0_, resc0_.descn as descn2_0_0_, resc0_.name as name3_0_0_, resc0_.priority as priority4_0_0_, resc0_.res_string as res5_0_0_, resc0_.res_type as res6_0_0_ from Resc resc0_ where resc0_.id=?
Hibernate: select roles0_.resc_id as resc2_0_1_, roles0_.role_id as role1_1_1_, role1_.id as id1_4_0_, role1_.descn as descn2_4_0_, role1_.name as name3_4_0_ from Resc_Role roles0_ inner join role role1_ on roles0_.role_id=role1_.id where roles0_.resc_id=?
Hibernate: select rescs0_.role_id as role1_4_1_, rescs0_.resc_id as resc2_1_1_, resc1_.id as id1_0_0_, resc1_.descn as descn2_0_0_, resc1_.name as name3_0_0_, resc1_.priority as priority4_0_0_, resc1_.res_string as res5_0_0_, resc1_.res_type as res6_0_0_ from Resc_Role rescs0_ inner join Resc resc1_ on rescs0_.resc_id=resc1_.id where rescs0_.role_id=?
Hibernate: select roles0_.resc_id as resc2_0_1_, roles0_.role_id as role1_1_1_, role1_.id as id1_4_0_, role1_.descn as descn2_4_0_, role1_.name as name3_4_0_ from Resc_Role roles0_ inner join role role1_ on roles0_.role_id=role1_.id where roles0_.resc_id=?
rs.getRes_string:/admin
第二次查询,直接从缓存读取
rs.getRes_string:/admin
7.报错处理
net.sf.ehcache.config.CacheConfiguration.isTerracottaClustered()
--检查maven依赖,确定引入的是ehcache-core
org.hibernate.cache.NoCacheRegionFactoryAvailableException: Second-level cache is used in the application, but property hibernate.cache.region.factory_class is not given, please either disable second level cache or set correct region factory class name to property hibernate.cache.region.factory_class (and make sure the second level cache provider, hibernate-infinispan, for example, is available in the classpath).
--添加<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>