简介
之前 spring boot 中讲了 mybatis-ehcache 配合 mybatis-pluse 使用实现二级缓存的配置 : https://my.oschina.net/u/3681868/blog/1814216 ; 这篇就来说一下传统 spring 或 springMVC 中它们的配置使用, 虽然理论实现方式都是相同,但配置上还是有些微区别, spring boot 中是开箱即用, spring 是需要声明 Bean 的, 所以记录下来,方便以后使用.
具体配置
1, 引入 Maven Jar :
<!-- 版本大于 2.0.8 MP的公共CRUD不能支持二级缓存 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus</artifactId>
<version>2.0.8</version>
<exclusions>
<exclusion>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generate</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>
2, 编写 src/main/resources/ehcache.xml (注意: 路径文件名不能改变, 负责Ehcache不能单独使用)
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="true">
<!-- 磁盘缓存位置 -->
<diskStore path="java.io.tmpdir" />
<!--
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
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="0"
timeToLiveSeconds="600"
memoryStoreEvictionPolicy="LRU" />
<!-- 自定义缓存 -->
<cache
name="testCache"
eternal="false"
maxElementsInMemory="1000"
overflowToDisk="false"
diskPersistent="false"
timeToIdleSeconds="5"
timeToLiveSeconds="5"
memoryStoreEvictionPolicy="LRU" />
</ehcache>
3, 编写 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: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/cache
http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- 启用缓存注解开关 Spring提供的基于的EhCacheManager实现的缓存管理器; 和spring-redis.xml中的只能使用一个 -->
<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
<property name="cacheManager" ref="cacheManagerFactory"/>
<property name="transactionAware" value="true"/>
</bean>
<!-- 如果有多个cacheManager要在bean加上p:shared="true" -->
<bean id="cacheManagerFactory" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<property name="shared" value="true"/> <!-- 必须开启,负责报错 -->
<property name="configLocation" value="classpath:ehcache.xml"/>
</bean>
</beans>
4, 将 spring-ehcache.xml 直接加载进 web.xml 或引入 spring-config.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.xsd">
<!-- 配置加载 -->
<import resource="classpath:spring/spring-mybatis.xml"/>
<import resource="classpath:spring/spring-redis.xml"/>
<import resource="classpath:spring/spring-ehcache.xml"/>
</beans>
5, web.xml 中:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-config.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
</listener>
6, 在 mybatis-config.xml 中开启全局缓存
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<!-- 全局映射器启用二级缓存 -->
<setting name="cacheEnabled" value="false"/>
<!-- 打印SQL -->
<setting name="logImpl" value="LOG4J"/>
</settings>
</configuration>
7, 将 mybatis-cofig.xml 引入 spring-mybatis.xml 配置文件:
<!-- MyBatis_Plus -->
<bean id="sqlSessionFactory"
class="com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.gy.spring.mvc.entity"/>
<property name="mapperLocations" value="classpath:sqlMapperXml/*.xml"/>
<property name="configLocation" value="classpath:spring/mybatis-config.xml"/>
<property name="plugins">
<array>
<!-- 分页插件配置 -->
<bean id="paginationInterceptor"
class="com.baomidou.mybatisplus.plugins.PaginationInterceptor" />
<!-- 乐观锁插件 -->
<!-- <bean id="optimisticLockerInterceptor"
class="com.baomidou.mybatisplus.plugins.OptimisticLockerInterceptor">
</bean> -->
</array>
</property>
</bean>
8, mybatis 的映射文件 mapper.xml 中使用:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gy.spring.mvc.mapper.UserMapper">
<!-- 使用EhCacheh开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
<property name="timeToIdleSeconds" value="3600"/>
<property name="timeToLiveSeconds" value="3600"/>
<property name="maxEntriesLocalHeap" value="1000"/>
<property name="maxEntriesLocalDisk" value="10000000"/>
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
<!-- 通用查询映射结果 -->
<resultMap id="BaseResultMap" type="com.gy.spring.mvc.entity.User">
<id column="id" property="id"/>
<result column="nickname" property="nickname"/>
<result column="money" property="money"/>
</resultMap>
<select id="listUser" resultMap="BaseResultMap">
SELECT id AS id,nickname,money
FROM user
</select>
</mapper>
全部配置完成, 可以测试;
9, ehcache 单独使用的工具类:
package com.gy.spring.mvc.common.tools;
import org.apache.log4j.Logger;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
/**
* 缓存工具
* @author geYang
* @date 2018-05-17
*/
public class EhcacheTool {
private static Logger logger = Logger.getLogger(EhcacheTool.class);
private static CacheManager cacheManager = CacheManager.create();
/**
* 添加缓存
*/
public static void put(String name, String k,Object v) {
Cache cache = cacheManager.getCache(name);
Element element = new Element(k, v);
cache.put(element);
putLog("添加缓存",name, k, v);
}
/**
* 获取缓存
*/
public static Object get(String name, String k) {
Cache cache = cacheManager.getCache(name);
Element element = cache.get(k);
Object v = null;
v = element == null ? null : element.getObjectValue();
putLog("获取缓存",name, k, v);
return v;
}
/**
* 清除所有缓存
*/
public static void removeAll(String name) {
Cache cache = cacheManager.getCache(name);
cache.removeAll();
putLog("清除所有缓存", name, null, null);
}
/**
* 清除指定缓存
*/
public static void remove(String name, String k) {
Cache cache = cacheManager.getCache(name);
boolean b = cache.remove(k);
putLog("清除指定缓存",name, k, b);
}
/**
* 日志打印
*/
private static void putLog(String method, String name, String k, Object v) {
logger.info(method+": name=" + name + ", K=" + k + ", V=" + v);
}
}
10, 测试工具类及打印结果:
package com.gy.spring.mvc;
import org.junit.Test;
import com.gy.spring.mvc.common.tools.EhcacheTool;
/**
* 缓存工具测试
* @author geYang
* @date 2018-05-17
*/
public class EhcacheToolTest {
private final static String CACHE_NAME_TEST = "testCache";
@Test
public void testPut() {
EhcacheTool.put(CACHE_NAME_TEST, "test", "testValue");
EhcacheTool.get(CACHE_NAME_TEST, "test");
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
EhcacheTool.get(CACHE_NAME_TEST, "test");
}
}
[com.gy.spring.mvc.common.tools.EhcacheTool] 添加缓存: name=testCache, K=test, V=testValue
[com.gy.spring.mvc.common.tools.EhcacheTool] 获取缓存: name=testCache, K=test, V=testValue
[com.gy.spring.mvc.common.tools.EhcacheTool] 获取缓存: name=testCache, K=test, V=null
因为我们配置的 testCache 为 5s 失效, 所以 10s 后获取 为空, 可以用来存储验证码之类的.
11, mybatis-pluse 二级缓存测试及打印:
@Test
public void test() {
System.out.println(userService.selectById(1));
System.out.println(userService.selectById(1));
System.out.println(userService.selectById(1));
}
[com.gy.spring.mvc.mapper.UserMapper] Cache Hit Ratio [com.gy.spring.mvc.mapper.UserMapper]: 0.0
[com.gy.spring.mvc.mapper.UserMapper.selectById] ==> Preparing: SELECT id AS id,nickname,money FROM user WHERE id=?
[com.gy.spring.mvc.mapper.UserMapper.selectById] ==> Parameters: 1(Integer)
[com.gy.spring.mvc.mapper.UserMapper.selectById] <== Total: 1
User{ id=1, nickname=aaa, money=100}
[com.gy.spring.mvc.mapper.UserMapper] Cache Hit Ratio [com.gy.spring.mvc.mapper.UserMapper]: 0.5
User{ id=1, nickname=aaa, money=100}
[com.gy.spring.mvc.mapper.UserMapper] Cache Hit Ratio [com.gy.spring.mvc.mapper.UserMapper]: 0.6666666666666666
总结
ehcache的配置终于完成啦, 希望能有所帮助.
具体源码会上传至: https://gitee.com/ge.yang/spring-demo