Spring-Mybatis-Pluse-Ehcache實現二級緩存

簡介

    之前 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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章