Ehcache在很多项目中都出现过,用法也比较简单。一般的加些配置就可以了,而且Ehcache可以对页面、对象、数据进行缓存,同时支持集群/分布式缓存。如果整合Spring、Mybatis也非常的简单,Spring对Ehcache的支持也非常好。EHCache支持内存和磁盘的缓存,支持LRU、LFU和FIFO多种淘汰算法,支持分布式的Cache。本文主要为大家介绍一下spring+mybatis+ehcahce注解实现缓存的步骤方法。
首先。需要先导入所需jar包
ehcache-core-2.4.4.jar
ehcache核心jar包
ehcache-spring-annotations-1.2.0.jar
ehcache结合spring注解实现包
guava-11.0.2.jar
ehcache的注解实现包
mybatis-ehcache-1.0.0.jar
ehcache+mybatis的实现包
第一部:在项目的classpath路径下面创建ehcache.xml
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../bin/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<!-- 缓存位置可以是自定义的硬盘地址也可以是JVM默认使用的缓存地址-->
<!--<diskStore path="d:\cache"/> -->
<defaultCache maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="30"
timeToLiveSeconds="30"
overflowToDisk="true"/>
<cache name="DEFAULT_CACHE"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskSpoolBufferSizeMB="30"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="userCache"
maxElementsInMemory="3000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LFU"
/>
<!--
配置自定义缓存
name:Cache的唯一标识
maxElementsInMemory:缓存中允许创建的最大对象数
maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大
eternal:Element是否永久有效,一但设置了,timeout将不起作用,对象永不过期。
timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,
两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,
如果该值是 0 就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值, 这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
overflowToDisk:内存不足时,是否启用磁盘缓存。
diskPersistent:是否缓存虚拟机重启期数据
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)
<cache name="SimplePageCachingFilter"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="900"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LFU" /> -->
</ehcache>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../bin/ehcache.xsd">
<diskStore path="java.io.tmpdir"/>
<!-- 缓存位置可以是自定义的硬盘地址也可以是JVM默认使用的缓存地址-->
<!--<diskStore path="d:\cache"/> -->
<defaultCache maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="30"
timeToLiveSeconds="30"
overflowToDisk="true"/>
<cache name="DEFAULT_CACHE"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskSpoolBufferSizeMB="30"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"
/>
<cache name="userCache"
maxElementsInMemory="3000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="3600"
timeToLiveSeconds="3600"
memoryStoreEvictionPolicy="LFU"
/>
<!--
配置自定义缓存
name:Cache的唯一标识
maxElementsInMemory:缓存中允许创建的最大对象数
maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大
eternal:Element是否永久有效,一但设置了,timeout将不起作用,对象永不过期。
timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,
两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效,
如果该值是 0 就意味着元素可以停顿无穷长的时间。
timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值, 这只能在元素不是永久驻留时有效,如果该值是0就意味着元素可以停顿无穷长的时间。
overflowToDisk:内存不足时,是否启用磁盘缓存。
diskPersistent:是否缓存虚拟机重启期数据
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
memoryStoreEvictionPolicy:缓存满了之后的淘汰算法。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)
<cache name="SimplePageCachingFilter"
maxElementsInMemory="10000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="900"
timeToLiveSeconds="1800"
memoryStoreEvictionPolicy="LFU" /> -->
</ehcache>
第二部
在classpath下面创建一个applicationContext-ehcache.xml的配置文件
<!-- /** * * 缓存配置 * * */ -->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ehcache="http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring
http://ehcache-spring-annotations.googlecode.com/svn/schema/ehcache-spring/ehcache-spring-1.1.xsd">
<!-- <ehcache:annotation-driven /> -->
<ehcache:annotation-driven cache-manager="ehcacheManager" ></ehcache:annotation-driven>
<ehcache:config cache-manager="ehcacheManager">
<ehcache:evict-expired-elements interval="60" />
</ehcache:config>
<bean id="ehcacheManager"
class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="configLocation" value="classpath:ehcache.xml" />
</bean>
</beans>
第三部 在applicationContext.xml配置文件中添加下面一行代码 将applicationContext-chcache.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<beans xmlns="http://www.springframework.org/schema/beans"
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
http://www.springframework.org/schema/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 加载ehcache缓存配置文件
说明:在这里我遇到了这样一个问题,当使用@Service等注解的方式将类声明到配置文件中时,
就需要将缓存配置import到主配置文件中,否则缓存会不起作用
如果是通过<bean>声明到配置文件中时,
则只需要在web.xml的contextConfigLocation中加入applicationContext-ehcache.xml即可,
不过还是推荐使用如下方式吧,因为这样不会有任何问题
-->
<import resource="classpath:applicationContext-ehcache.xml"/>
<mapper namespace="com.wporoad.app.dao.UserMapper">
<cache type="org.mybatis.caches.ehcache.LoggingEhcache">
<property name="timeToIdleSeconds" value="3600"/><!--1 hour-->
<property name="timeToLiveSeconds" value="3600"/><!--1 hour-->
<property name="maxEntriesLocalHeap" value="1000"/>
<property name="maxEntriesLocalDisk" value="10000000"/>
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
<!-- 以下两个<cache>标签二选一,第一个可以输出日志,第二个不输出日志 -->
<!-- <cache type="org.mybatis.caches.ehcache.LoggingEhcache" />
<cache type="org.mybatis.caches.ehcache.EhcacheCache" /> -->
<resultMap id="UserMap" type="com.wporoad.app.entity.User">
<result property="id" column="ID" />
<result property="userName" column="USERNAME" />
<result property="password" column="PASSWORD" />
<result property="email" column="EMAIL" />
</resultMap>
<!-- 查询所有用户信息 -->
<select id="queryUsers" resultMap="UserMap" useCache="true">
SELECT * FROM USER
</select>
</mapper>
说明:在这里我遇到了这样一个问题,当使用@Service等注解的方式将类声明到配置文件中时,
就需要将缓存配置import到主配置文件中,否则缓存会不起作用
如果是通过<bean>声明到配置文件中时,
则只需要在web.xml的contextConfigLocation中加入applicationContext-ehcache.xml即可,
不过还是推荐使用如下方式吧,因为这样不会有任何问题
-->
<import resource="classpath:applicationContext-ehcache.xml"/>
第四部 最后在service的impl类里面为要实现缓存的方法加上注解就可以了(注:此注解只能加在serviceimpl类里面才能实现缓存的效果)
/**
* 列出所有用户
*/
@Cacheable(cacheName="userCache") //这里的cacheName要跟ehcache.xml中保持一致</strong>
public List<User> queryUsers() {
List<User> userList = userMapper.queryUsers();
return userList;
}
* 列出所有用户
*/
@Cacheable(cacheName="userCache") //这里的cacheName要跟ehcache.xml中保持一致</strong>
public List<User> queryUsers() {
List<User> userList = userMapper.queryUsers();
return userList;
}
第五步 还要在想实现缓存的mapper.xml中配置上:
<cache type="org.mybatis.caches.ehcache.LoggingEhcache">
<property name="timeToIdleSeconds" value="3600"/><!--1 hour-->
<property name="timeToLiveSeconds" value="3600"/><!--1 hour-->
<property name="maxEntriesLocalHeap" value="1000"/>
<property name="maxEntriesLocalDisk" value="10000000"/>
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
<!-- 以下两个<cache>标签二选一,第一个可以输出日志,第二个不输出日志 -->
<!-- <cache type="org.mybatis.caches.ehcache.LoggingEhcache" />
<cache type="org.mybatis.caches.ehcache.EhcacheCache" /> -->
<resultMap id="UserMap" type="com.wporoad.app.entity.User">
<result property="id" column="ID" />
<result property="userName" column="USERNAME" />
<result property="password" column="PASSWORD" />
<result property="email" column="EMAIL" />
</resultMap>
<!-- 查询所有用户信息 -->
<select id="queryUsers" resultMap="UserMap" useCache="true">
SELECT * FROM USER
</select>
</mapper>
做完这五部基本就实现了
Ehcach的注解缓存。大家可以自己写一个test.java进行测试。
这是我简单的测试类写法。大家可以将毫秒数也打出来,那样更精确一些。
System.out.println("~~~~~~~~~~~1111~~~~~~~~~~>"+new Date());
userService.queryUsers();
System.out.println("~~~~~~~~~~~22222~~~~~~~~~~>"+new Date());
userService.queryUsers();
System.out.println("~~~~~~~~~~~33333~~~~~~~~~~>"+new Date());
userService.queryUsers();
System.out.println("~~~~~~~~~~~22222~~~~~~~~~~>"+new Date());
userService.queryUsers();
System.out.println("~~~~~~~~~~~33333~~~~~~~~~~>"+new Date());
~~~~~~~~~~~1111~~~~~~~~~~>Sat Jan 23 12:04:53 CST 2016
~~~~~~~~~~~22222~~~~~~~~~~>Sat Jan 23 12:04:54 CST 2016
~~~~~~~~~~~33333~~~~~~~~~~>Sat Jan 23 12:04:54 CST 2016
~~~~~~~~~~~22222~~~~~~~~~~>Sat Jan 23 12:04:54 CST 2016
~~~~~~~~~~~33333~~~~~~~~~~>Sat Jan 23 12:04:54 CST 2016
从上面输出的结果来看。在查询第一次和第二次查询之间花费了1秒时间,第二次到第三次之间花费了不到一秒。当然大家可以将库表中数据量提高一些,我的库表字段才300多条。
好了 这就是我总结的一些配置方法 大家有什么疑问 可以留言给我 如有不对之处请多指正。