网上有很多关于spring+hibernate 二级缓存的配置文章,但是java使用实例不是很多,所以我把这两个加在一起来写一个文章,一个方便自己查阅,一方面希望能够给查资料的人们提供些许方便。
这里使用的环境:spring3.0+hibernate3.2+ehcache。相关环境配置和jar包引入略。
配置:
1、hibernate-mapping.xml配置文件中添加:
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
2、Hibernate允许在类和集合的粒度上设置第二级缓存。在映射文件中,<class>和<set>元素都有一个<cache>子元素,这个子元素用来配置二级缓存。
示例:以category(产品类别)和product(产品)的映射为例:
修改要配置缓存的那个持久化类的对象关系映射文件:
Category.hbm.xml
<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="org.qiujy.domain.cachedemo.Category" table="categories"> <!— 配置缓存,必须紧跟在class元素后面 对缓存中的Category对象采用读写型的并发访问策略 --> <cache usage="read-write"/> <id name="id" type="java.lang.Long"> <column name="id" /> <generator class="native" /> </id> <!-- 配置版本号,必须紧跟在id元素后面 --> <version name="version" column="version" type="java.lang.Long" /> <property name="name" type="java.lang.String"> <column name="name" length="32" not-null="true"/> </property> <property name="description" type="java.lang.String"> <column name="description" length="255"/> </property> <set name="products" table="products" cascade="all" inverse="true"> <!-- Hibernate只会缓存对象的简单属性的值, 要缓存集合属性,必须在集合元素中也加入<cache>子元素 而Hibernate仅仅是把与当前持久对象关联的对象的OID存放到缓存中。 如果希望把整个关联的对象的所有数据都存入缓存, 则要在相应关联的对象的映射文件中配置<cache>元素 --> <cache usage="read-write"/> <key column="categoryId" not-null="true"/> <one-to-many class="org.qiujy.domain.cachedemo.Product"/> </set> </class> </hibernate-mapping>
Product.hbm.xml
3、编辑ehcache.xml文件:<?xml version="1.0" encoding="utf-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="org.qiujy.domain.cachedemo.Product" table="products"> <cache usage="read-write"/> <id name="id" type="java.lang.Long"> <column name="id" /> <generator class="native" /> </id> <!-- 配置版本号,必须紧跟在id元素后面 --> <version name="version" column="version" type="java.lang.Long" /> <property name="name" type="java.lang.String"> <column name="name" length="32" not-null="true"/> </property> <property name="description" type="java.lang.String"> <column name="description" length="255"/> </property> <property name="unitCost" type="java.lang.Double"> <column name="unitCost" /> </property> <property name="pubTime" type="java.util.Date"> <column name="pubTime" not-null="true" /> </property> <many-to-one name="category" column="categoryId" class="org.qiujy.domain.cachedemo.Category" cascade="save-update" not-null="true"> </many-to-one> </class> </hibernate-mapping>
<ehcache> <diskStore path="c:\\ehcache\"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" /> <!-- 设置Category类的缓存的数据过期策略 --> <cache name="org.qiujy.domain.cachedemo.Category" maxElementsInMemory="100" eternal="true" timeToIdleSeconds="0" timeToLiveSeconds="0" overflowToDisk="false" /> <!-- 设置Category类的products集合的缓存的数据过期策略 --> <cache name="org.qiujy.domain.cachedemo.Category.products" maxElementsInMemory="500" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" /> <cache name="org.qiujy.domain.cachedemo.Product" maxElementsInMemory="500" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600" overflowToDisk="true" />
<cache name="workUnitHisCache" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="2400" timeToLiveSeconds="2400" overflowToDisk="false"/> </ehcache>
到此基本配置文件完成了。
使用:(以workUnitHisCache为例,上面两个是为了说明多对一关系的配置,最后一个的hbm.xml文件没有贴出来,知道怎么配置就可以了)
代码:
@Service public class WorkUnitHisServiceImpl { private static final Logger log = LoggerFactory.getLogger(WorkUnitHisServiceImpl.class); @Autowired private ITestdao testdao; @Autowired //spring注解方式注入cache private Cache workUnitHisCache; private Boolean useCache = true; @SuppressWarnings("unchecked") @Override public PageResult<Test> test( String condition) { //在缓存中取值(如果缓存中没有值,则从数据库中取值) PageResultVO<WorkUnitHisCount> pageCache = null; if (this.useCache) { //是否使用cache if (log.isDebugEnabled()) { log.debug("WorkUnitHisCount缓存开启,从缓存中获取WorkUnitHisCount,typeCode:" + ""); } //在缓存中取值,get()参数为放入缓存中的key Element element = this.workUnitHisCache.get(condition); if (element != null && element.getObjectValue() != null) { //缓存中放入什么,则此处可以取出什么 pageCache = (PageResultVO<WorkUnitHisCount>)element.getObjectValue(); } } if (pageCache == null) { //如果该对象为null,则缓存中没有对象,需要从数据库中取数据并放入到缓存中 if (log.isDebugEnabled()) { log.debug("从数据库中获取WorkUnitHisCount,typeCode:" + "" ); } //在数据库中取值 pageCache = testdao.testget(condition); //将结果放入到缓存中 if (this.useCache) { Element element = new Element(condition, pageCache); this.workUnitHisCache.put(element); } } return pageCache; } }
其中:
@Autowired
private Cache workUnitHisCache;
如果不采用注解的方式,java类中增加get、set方法,spring配置文件中如下配置:
http://blog.csdn.net/sundenskyqq/article/details/8244798<?xml version="1.0" encoding="UTF-8" standalone="no"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- ================================================ --> <!-- echcache extention config --> <!-- ================================================ --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml"/> </bean > <bean id ="workUnitHisCache" class ="org.springframework.cache.ehcache.EhCacheFactoryBean"> <property name="cacheManager" ref="cacheManager" /> <property name="cacheName" value="workUnitHisCache" /> </bean> </beans>
http://blog.csdn.net/sundenskyqq/article/details/8244798