spring boot 集成 ehCache

說明

       今天在作統計報表的時候,考慮到數據比較多,因此在項目中集成ehCache減輕數據庫請求壓力。看似簡單,網上參考也比較多,可是還遇到了幾處坑,在此記錄一下。 ⊙﹏⊙bjava

隨手筆記,比較簡單,想要具體瞭解的能夠網上看看大神的博客spring

問題

    (1)、springboot集成了ehcache,配置了過時時間timeToIdleSeconds,發現就是不生效,問度娘後才知道須要在properties文件中指定緩存類型,否則spring boot 使用默認SimpleCacheConfiguration,不是用的ehcache。數據庫

   (2)、測試的時候第一次請求接口返回正常數據,第二次查詢緩存的時候會報java.io.Serializable這個錯,是由於我返回的實體類沒作序列化。緩存

               解決方案在下面springboot

一、首先引入依賴在pom.xml文件中

<!--開啓 cache 緩存-->
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-cache</artifactId>
      </dependency>
      <!-- ehcache 緩存 -->
      <dependency>
          <groupId>net.sf.ehcache</groupId>
          <artifactId>ehcache</artifactId>
      </dependency>

二、引入配置文件 ehcache.xml(本身手殘名字寫錯ehcach,致使啓動報錯,加載不到配置,懵逼。。。。。)

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <diskStore path="java.io.tmpdir"/>
  <!--defaultCache:echcache的默認緩存策略  -->
  <!--
        緩存配置
           diskStore:指定數據在磁盤中的存儲位置。
           name:緩存名稱。
           defaultCache:當藉助CacheManager.add("demoCache")建立Cache時,EhCache便會採用<defalutCache/>指定的的管理策略,如下屬性是必須的:
           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"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </defaultCache>
    <cache name="userCache"
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <persistence strategy="localTempSwap"/>
    </cache>
</ehcache>

三、在properties文件中指定緩存類型和加載xml,也就是我上面說的問題 」(1)「。xml也能夠用@ImportResource註解直接在spring boot啓動類配置。

spring.cache.type=ehcache
spring.cache.ehcache.config=classpath:META-INF/mybatis/ehcache.xml

四、在spring boot 啓動類也要開啓緩存註解@EnableCaching,不然緩存不生效。以下

 

五、以上集成工做已經完成,那如何在代碼中使用呢? 以下mybatis

/**
	 * 查詢請求記錄數據統計
	 * 
	 * @param docNos
	 * @return
	 */
	@Cacheable(key = "#startDate+'-'+#endDate+'-'+#type",value="userCache")
	public ResponseMessage<List<Map<String, Object>>> selectReport(String startDate, String endDate, String docTemplateCode,String type) {
		ResponseMessage<List<Map<String, Object>>> rsdto = new ResponseMessage<>();
		List<Map<String, Object>> list=new ArrayList<>();
		if(StringUtils.isBlank(startDate) || StringUtils.isBlank(endDate)) {
			ResponseUtil.setResult(rsdto, null, ErrorCodeEnum.PARAMERROR, false);
			return rsdto;
		}
		/*if(StringUtils.isBlank(docTemplateCode)) {
			ResponseUtil.setResult(rsdto, null, ErrorCodeEnum.PARAMERROR, false);
			return rsdto;
		}*/
		if(StringUtils.isBlank(type)) {
			ResponseUtil.setResult(rsdto, null, ErrorCodeEnum.PARAMERROR, false);
			return rsdto;
		}
		Integer length=0;
		try {
		    length= ReportTypeEnum.getEnum(type).getValue();
		    list=docRecordTunnel.selectReportByDateTime(startDate, endDate, docTemplateCode, length);
			ResponseUtil.setResult(rsdto, list, ErrorCodeEnum.SUCCESS,true);
		} catch (Exception e) {
			log.error("DocRecordController.selectReport查詢失敗", e);
			ResponseUtil.setResult(rsdto, null, ErrorCodeEnum.ERROR, false);
		}
		return rsdto;
	}

 

注: 返回的實體類須要作序列化,不然查詢緩存的時候會報錯。以下圖spring-boot

 

通常狀況下,咱們在Sercive層進行對緩存的操做。先介紹 Ehcache 在 Spring 中的註解:
* @Cacheable : Spring在每次執行前都會檢查Cache中是否存在相同key的緩存元素,若是存在就再也不執行該方法,而是直接從緩存中獲取結果進行返回,不然纔會執行並將返回結果存入指定的緩存中。
* @CacheEvict : 清除緩存。 
* @CachePut : @CachePut也能夠聲明一個方法支持緩存功能。使用@CachePut標註的方法在執行前不會去檢查緩存中是否存在以前執行過的結果,而是每次都會執行該方法,並將執行結果以鍵值對的形式存入指定的緩存中。 測試

簡單來講,Cacheable 通常用於查詢,CacheEvict 用於新增清除緩存,CachePut 用於更新;其中,value 指的是 ehcache.xml 中的緩存策略空間;key 指的是緩存的標識,同時能夠用 # 來引用參數。上面代碼引用參數爲多個組合做爲緩存key 。spa

五、啓動項目,測試結果。具體代碼我就再也不貼了。

相關文章
相關標籤/搜索