我的spring是3.1的,因为项目需求,需要在查询时候加上缓存,小白一个,完全没有用过缓存(ehcache),摸索了一天终于会了一点通过注解来使用ehcache进行缓存,立刻给记录下来。
首先 我的ehcache.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache> <diskStore path="java.io.tmpdir" /> <!-- Mandatory Default Cache configuration. These settings will be applied to caches created programmtically using CacheManager.add(String cacheName) --> <!--name:缓存名称。 maxElementsInMemory:缓存最大个数。 eternal:对象是否永久有效,一但设置了,timeout将不起作用。 timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。 timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。 overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。 diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。 maxElementsOnDisk:硬盘最大缓存个数。 diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 clearOnFlush:内存数量最大时是否清除。 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> <cache name="hibernateCache" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="10000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> </ehcache>
然后 我的spring-ehcache.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:cache="http://www.springframework.org/schema/cache" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd"> <bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml" /> <property name="shared" value="true" /> </bean> <!-- 默认是cacheManager --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="cacheManagerFactory" /> </bean> <!-- 支持缓存注解 --> <cache:annotation-driven cache-manager="cacheManager" /> </beans>
然后 就是测试实现了,我只使用了@Cacheable注解,所以就先简单说下这个注解到功能,被他注解到方法被请求时,首先根据你的key去缓存中查看是否已经有了缓存,如果有的话就不会进行查询操作,直接使用缓存中的数据,如果在缓存中没有查到数据就会执行查询方法,然后按照key-value形式将查出来到值缓存到内存中,当然内存不是很大,他也支持内存不够时放进硬盘中(注意:如果需要存进硬盘,需要将数据序列化),这个在ehcache.xml中的参数配置都有详细说明,我就不意义赘述了,再说一下@Cacheable注解的参数,他又key、value、和condition 其中到key 就是村进缓存中的key ,value时ehcache.xml中cache的name值,condition是用来进行有条件缓存的,其中value是必须的,key值建议填写,因为这样更能够保证唯一(如果是做不固定条件查询就更家需要了),它支持spEl表达式。好了,废话了这么多(网上一大堆,就是想加固一下印象),下面贴出自己到测试代码:
我的service层:
我的service层的一个方法,用来调用dao层的一个备注接缓存的方法 public Map<String, Object> getDetailList(Map<String, String> map,Page page){ deList = detailDao.getList(map,page,key); }
我的dao层(代码太多没有贴完,其中@cacheable中value值可以改成hibernateCache,实现效果相同,只是想说value对应到值。):
import org.springframework.cache.annotation.Cacheable; @Override @Cacheable(value = "detailQueryCache",key="#key") public List<Map<String, Object>> getList(Map<String, String> map,Page page,String key){ System.out.println("第一次请求"); return getDegetDetailList(map,0,0); } 上面一行是我注解使用的包
这里有一个细节就是我把两个方法放到了两个类中,这个是必须的,这也是困扰了我几个小时到问题,说下结论:不能在同一个类中调用被注解了缓存的方法;
好了,这时第一次点击查询时,会打印出第一次请求,第二次再次点击查询时就不会打印出任何内容了。
完了,有什么不对到地方,欢迎大家指出。谢谢