Hibernate的二级缓存功能是通过配置二级缓存插件来实现的,常用的二级缓存插件包括EHCache,OSCache,SwarmCache和JBossCache。本文主要介绍Hibernate缓存插件中EHCache配置。
1、引入EHCache相关jar包
<dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-core</artifactId> <version>2.4.3</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.1.4.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>4.1.4.RELEASE</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>4.3.8.Final</version> </dependency>
2、ehcache.xml配置
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <!-- 指定一个文件目录,当EhCache把数据写到硬盘上时,将把数据写到这个文件目录下 --> <!-- <diskStore path="java.io.tmpdir"/> --> <diskStore path="d:/ehcache"/> <!-- 设定缓存的默认数据过期策略 --> <defaultCache maxElementsInMemory="100" eternal="false" overflowToDisk="true" timeToIdleSeconds="10" timeToLiveSeconds="20" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"/> <!-- 该配置为spring缓存中的 --> <!-- <cache name="cacheTest" maxElementsInMemory="10" eternal="false" overflowToDisk="true" timeToIdleSeconds="3" timeToLiveSeconds="20"/> --> </ehcache>
参数解释:
diskStore 缓存数据文件的存储目录
defaultCache 存的默认数据过期策略
cache 设置具体的命名缓存的数据过期策略
每个命名缓存代表一个缓存区域,命名缓存机制允许用户在每个类以及类的每个集合的粒度上设置数据过期策略;
在defaultCache元素中:
maxElementsInMemory属性设置缓存对象的最大数目;
eternal属性指定是否永不过期,true为不过期,false为过期;
timeToldleSeconds属性设置对象处于空闲状态的最大秒数;
timeToLiveSeconds属性设置对象处于缓存状态的最大秒数;
overflowToDisk属性设置内存溢出时是否将溢出对象写入硬盘;
3、config.properties文件配置
#hibernate config hibernate.dialect = org.hibernate.dialect.MySQLDialect hibernate.show_sql = true hibernate.format_sql = false hibernate.hbm2ddl.auto = update hibernate.cache.use_second_level_cache = true hibernate.cache.use_query_cache = true hibernate.cache.provider_configuration_file_resource_path = ehcache.xml #hibernate4 config hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.EhCacheRegionFactory #hibernate3 config #hibernate.cache.provider_class = org.hibernate.cache.EhCacheProvider
4、spring-hibernate.xml文件配置,配置到sessionfactory标签当中
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> <!-- 注入数据源 相关信息看源码 --> <property name="dataSource" ref="dataSource" /> <!-- hibernate配置信息 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">${hibernate.dialect}</prop> <prop key="hibernate.show_sql">${hibernate.show_sql}</prop> <prop key="hibernate.format_sql">${hibernate.format_sql}</prop> <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop> <!-- 配置二级缓存 --> <prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop> <!-- hibernate4的二级缓存配置 --> <prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop> <!-- hibernate3的二级缓存配置 --> <!-- <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property> --> <!-- 开启查询缓存 --> <prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop> <!-- 发现没有任何作用 --> <prop key="hibernate.cache.provider_configuration_file_resource_path">${hibernate.cache.provider_configuration_file_resource_path}</prop> </props> </property> <!-- 扫描hibernate注解配置的model --> <property name="packagesToScan" value="com.tz.model" /> <!-- hbm方式配置 --> <!--<property name="mappingDirectoryLocations"> <list> <value>classpath:com/tz/model</value> </list> </property> --> </bean>
5、添加需要进行二级缓存的实体类注解
6、测试是否成功
Session session = sf.openSession(); session.beginTransaction(); List<User> list = (List<User>)session.createQuery("from User").setCacheable(true).list(); for(User u:list){ System.out.println(u.getName()); } session.getTransaction().commit(); session.close(); System.out.println("-----------------分割线------------------"); Session session2 = sf.openSession(); session2.beginTransaction(); List<User> list2 = (List<User>)session2.createQuery("from User").setCacheable(true).list(); for(User u:list2){ System.out.println(u.getName()); } session2.getTransaction().commit(); session2.close();
说明:
需要使用查询缓存时,需要设置 setCacheable(true)
因为二级缓存是sessionfactory级别的缓存,可以跨域session进行调用,所以检验其是否成功运用了两个session。
第一个session使用查询缓存和list方式,查询出该表的所以实体信息,查询缓存将实体的id集合进行缓存,二级缓存则将其中的实体进行缓存。
第二个session执行同样的查询语句,所以直接从查询缓存中提取第一次查询结果集即实体id的集合,然后再根据实体id从二级缓存中提取实体信息,所以第二个session没有进行任何数据库操作。
执行结果:
二级缓存和查询缓存结果显示均成功。