ibatis 實現cache 註解+cacheModel實現

  一、使用cacheModel 在sqlMap中直接標註哪個方法需要配置緩存
  二、使用bean的方式 通過@Cacheable註解標註對應的cache
cacheModel 相關屬性

type 取值類型:
◆"MEMORY” (com.ibatis.db.sqlmap.cache.memory.MemoryCacheController) 。MEMORY cache 實現使用 reference 類型來管理 cache 的行爲。垃圾收集器可以根據 reference類型判斷是否要回收 cache 中的數據。MEMORY實現適用於沒有統一的對象重用模式的應用,或內存不足的應用。

◆“LRU” (com.ibatis.db.sqlmap.cache.lru.LruCacheController) 。LRU Cache 實現用“近期最少使用”原則來確定如何從 Cache 中清除對象。當 Cache溢出時,最近最少使用的對象將被從 Cache 中清除。使用這種方法,如果一個特定的對象總是被使用,它將保留在 Cache 中,而且被清除的可能性最小。對於在較長的期間內,某些用戶經常使用某些特定對象的情況(例如,在 PaginatedList 和常用的查詢關鍵字結果集中翻頁) ,LRU Cache 是一個不錯的選擇。

◆“FIFO” (com.ibatis.db.sqlmap.cache.fifo.FifoCacheController) 。FIFO Cache 實現用“先進先出”原則來確定如何從 Cache 中清除對象。當 Cache 溢出時,最先進入 Cache 的對象將從 Cache 中清除。對於短時間內持續引用特定的查詢而後很可能不再使用的情況,FIFO Cache 是很好的選擇。

◆“OSCACHE” (com.ibatis.db.sqlmap.cache.oscache.OSCacheController)  。OSCACHE Cache 實現是OSCache2.0緩存引擎的一個 Plugin。它具有高度的可配置性,分佈式,高度的靈活性。

其他屬性:
serialize:只有在readOnly爲false的情況下才生效,因爲在readOnly爲true時,所有數據對象相同,只有可讀寫時,纔會出現不同的session擁有不同的數據對象副本。
flushInterval:指定緩存自動刷新的時間,可以爲hours,minutes,seconds,milliseconds.
flushOnExecute:指定在發生哪些操作時,更新緩存。
property:不同type的cachemodel有不同的屬性。


  一、使用cacheModel 在sqlMap中直接標註哪個方法需要配置緩存
這裏加上Cowboys namespace 是因爲核心配置sql-map中配置了useStatementNamespaces="true"。
     <cacheModel id="ehCache" type="LRU" readOnly="true"
           serialize="true">
           <flushInterval hours="24" />
           <flushOnExecute statement="Cowboys.getById" />
           <property value="500" name="size" />
     </cacheModel>
------------------------------------------------------------------------
<select id="getById" resultMap="cowboysResultMap" cacheModel="ehCache">
           select
           <include refid="commonColumns" />
        <![CDATA[
             from t_dat_dict
             where
                   data_cd = #id#
         ]]>
     </select>
sql-map.xml

<sqlMapConfig>
     <settings cacheModelsEnabled="true" lazyLoadingEnabled="true"
           enhancementEnabled="true" maxSessions="128" maxTransactions="50"
           maxRequests="512" useStatementNamespaces="true" />
     <!-- 這裏無需配置sqlMap,可以通過spring的配置加載某個目錄的多個SqlMap.xml -->
     <sqlMap resource="/net/spring/entity/sqlMap/CowboysSqlMap.xml" />
</sqlMapConfig>
測試結果:


2017-08-22 16:22:06,506 耗時:182090 [日誌來自:web.servlet.DispatcherServlet            日誌類型: DEBUG 日誌內容:DispatcherServlet with name 'spring' processing GET request for [/SpringMvcVsRestVsThreadpool/rest/cowboys/v2/4782]]
2017-08-22 16:22:06,506 耗時:182090 [日誌來自:.annotation.RequestMappingHandlerMapping 日誌類型: DEBUG 日誌內容:Looking up handler method for path /cowboys/v2/4782]
2017-08-22 16:22:06,512 耗時:182096 [日誌來自:.annotation.RequestMappingHandlerMapping 日誌類型: DEBUG 日誌內容:Returning handler method [public net.spring.entity.Cowboys net.spring.controller.CowboysController.getOne(java.lang.String)]]
2017-08-22 16:22:06,512 耗時:182096 [日誌來自:ctory.support.DefaultListableBeanFactory 日誌類型: DEBUG 日誌內容:Returning cached instance of singleton bean 'cowboysController']
2017-08-22 16:22:06,513 耗時:182097 [日誌來自:web.servlet.DispatcherServlet            日誌類型: DEBUG 日誌內容:Last-Modified value for [/SpringMvcVsRestVsThreadpool/rest/cowboys/v2/4782] is: -1]
2017-08-22 16:22:06,538 耗時:182122 [日誌來自:orm.ibatis.SqlMapClientTemplate          日誌類型: DEBUG 日誌內容:Opened SqlMapSession [com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl@1db7bce] for iBATIS operation]
2017-08-22 16:22:06,546 耗時:182130 [日誌來自:jdbc.datasource.DataSourceUtils          日誌類型: DEBUG 日誌內容:Fetching JDBC Connection from DataSource]
2017-08-22 16:22:06,945 耗時:182529 [日誌來自:java.sql.Connection                      日誌類型: DEBUG 日誌內容:{conn-100000} Connection]
2017-08-22 16:22:06,949 耗時:182533 [日誌來自:orm.ibatis.SqlMapClientTemplate          日誌類型: DEBUG 日誌內容:Obtained JDBC Connection [jdbc:oracle:thin:@192.168.70.102:1521:ora11gR2, UserName=INTER, Oracle JDBC driver] for iBATIS operation]
2017-08-22 16:22:06,949 耗時:182533 [日誌來自:engine.cache.CacheModel                  日誌類型: DEBUG 日誌內容:Cache 'Cowboys.ehCache': cache miss]
2017-08-22 16:22:06,952 耗時:182536 [日誌來自:java.sql.Connection                      日誌類型: DEBUG 日誌內容:{conn-100000} Preparing Statement:    select          data_cd ,          data_nm ,          data_type ,          data_kind                               from t_dat_dict          where           data_cd = ?         ]
2017-08-22 16:22:07,065 耗時:182649 [日誌來自:java.sql.PreparedStatement               日誌類型: DEBUG 日誌內容:{pstm-100001} Executing Statement:    select          data_cd ,          data_nm ,          data_type ,          data_kind                               from t_dat_dict          where           data_cd = ?         ]
2017-08-22 16:22:07,065 耗時:182649 [日誌來自:java.sql.PreparedStatement               日誌類型: DEBUG 日誌內容:{pstm-100001} Parameters: [4782]]
2017-08-22 16:22:07,065 耗時:182649 [日誌來自:java.sql.PreparedStatement               日誌類型: DEBUG 日誌內容:{pstm-100001} Types: [java.lang.String]]
2017-08-22 16:22:07,094 耗時:182678 [日誌來自:java.sql.ResultSet                       日誌類型: DEBUG 日誌內容:{rset-100002} ResultSet]
2017-08-22 16:22:07,109 耗時:182693 [日誌來自:java.sql.ResultSet                       日誌類型: DEBUG 日誌內容:{rset-100002} Header: [data_cd, data_nm, data_type, data_kind]]
2017-08-22 16:22:07,109 耗時:182693 [日誌來自:java.sql.ResultSet                       日誌類型: DEBUG 日誌內容:{rset-100002} Result: [4782, 過橋費, 0001, 0]]
2017-08-22 16:22:07,112 耗時:182696 [日誌來自:engine.cache.CacheModel                  日誌類型: DEBUG 日誌內容:Cache 'Cowboys.ehCache': flushed]
2017-08-22 16:22:07,112 耗時:182696 [日誌來自:engine.cache.CacheModel                  日誌類型: DEBUG 日誌內容:Cache 'Cowboys.ehCache': stored object '[Cowboys [id=4782, name=過橋費, age=0001, level=0]]']
2017-08-22 16:22:07,112 耗時:182696 [日誌來自:jdbc.datasource.DataSourceUtils          日誌類型: DEBUG 日誌內容:Returning JDBC Connection to DataSource]
2017-08-22 16:22:07,176 耗時:182760 [日誌來自:ation.RequestResponseBodyMethodProcessor 日誌類型: DEBUG 日誌內容:Written [Cowboys [id=4782, name=過橋費, age=0001, level=0]] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@8b85eb]]
2017-08-22 16:22:07,177 耗時:182761 [日誌來自:web.servlet.DispatcherServlet            日誌類型: DEBUG 日誌內容:Null ModelAndView returned to DispatcherServlet with name 'spring': assuming HandlerAdapter completed request handling]
2017-08-22 16:22:07,178 耗時:182762 [日誌來自:web.servlet.DispatcherServlet            日誌類型: DEBUG 日誌內容:Successfully completed request]
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2017-08-22 16:22:18,500 耗時:194084 [日誌來自:web.servlet.DispatcherServlet            日誌類型: DEBUG 日誌內容:DispatcherServlet with name 'spring' processing GET request for [/SpringMvcVsRestVsThreadpool/rest/cowboys/v2/4782]]
2017-08-22 16:22:18,500 耗時:194084 [日誌來自:.annotation.RequestMappingHandlerMapping 日誌類型: DEBUG 日誌內容:Looking up handler method for path /cowboys/v2/4782]
2017-08-22 16:22:18,502 耗時:194086 [日誌來自:.annotation.RequestMappingHandlerMapping 日誌類型: DEBUG 日誌內容:Returning handler method [public net.spring.entity.Cowboys net.spring.controller.CowboysController.getOne(java.lang.String)]]
2017-08-22 16:22:18,502 耗時:194086 [日誌來自:ctory.support.DefaultListableBeanFactory 日誌類型: DEBUG 日誌內容:Returning cached instance of singleton bean 'cowboysController']
2017-08-22 16:22:18,502 耗時:194086 [日誌來自:web.servlet.DispatcherServlet            日誌類型: DEBUG 日誌內容:Last-Modified value for [/SpringMvcVsRestVsThreadpool/rest/cowboys/v2/4782] is: -1]
2017-08-22 16:22:18,503 耗時:194087 [日誌來自:orm.ibatis.SqlMapClientTemplate          日誌類型: DEBUG 日誌內容:Opened SqlMapSession [com.ibatis.sqlmap.engine.impl.SqlMapSessionImpl@44fa35] for iBATIS operation]
2017-08-22 16:22:18,503 耗時:194087 [日誌來自:jdbc.datasource.DataSourceUtils          日誌類型: DEBUG 日誌內容:Fetching JDBC Connection from DataSource]
2017-08-22 16:22:18,508 耗時:194092 [日誌來自:java.sql.Connection                      日誌類型: DEBUG 日誌內容:{conn-100003} Connection]
2017-08-22 16:22:18,512 耗時:194096 [日誌來自:orm.ibatis.SqlMapClientTemplate          日誌類型: DEBUG 日誌內容:Obtained JDBC Connection [jdbc:oracle:thin:@192.168.70.102:1521:ora11gR2, UserName=INTER, Oracle JDBC driver] for iBATIS operation]
2017-08-22 16:22:18,512 耗時:194096 [日誌來自:engine.cache.CacheModel                  日誌類型: DEBUG 日誌內容:Cache 'Cowboys.ehCache': retrieved object '[Cowboys [id=4782, name=過橋費, age=0001, level=0]]']
2017-08-22 16:22:18,513 耗時:194097 [日誌來自:jdbc.datasource.DataSourceUtils          日誌類型: DEBUG 日誌內容:Returning JDBC Connection to DataSource]
2017-08-22 16:22:18,515 耗時:194099 [日誌來自:ation.RequestResponseBodyMethodProcessor 日誌類型: DEBUG 日誌內容:Written [Cowboys [id=4782, name=過橋費, age=0001, level=0]] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJackson2HttpMessageConverter@8b85eb]]
2017-08-22 16:22:18,515 耗時:194099 [日誌來自:web.servlet.DispatcherServlet            日誌類型: DEBUG 日誌內容:Null ModelAndView returned to DispatcherServlet with name 'spring': assuming HandlerAdapter completed request handling]
2017-08-22 16:22:18,516 耗時:194100 [日誌來自:web.servlet.DispatcherServlet            日誌類型: DEBUG 日誌內容:Successfully completed request]

通過日誌可以看出第一遍取自數據庫,第二遍從緩存中獲取!
---------------------------------------------------------------------------------------------------------------------------------------
二、通過bean注入+註解方式實現

bean配置xml文件:
<cache:annotation-driven cache-manager="cacheManager" />
     <!--聲明一個緩存管理器(EhCacheCacheManager) 這裏的實現代碼是通過傳入EhCache的CacheManager實例實現的 -->
     <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager">
           <property name="cacheManager" ref="ehcache"></property>
     </bean>

     <bean id="ehcache"
          class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
           <!-- 指定 ehcache配置文件路徑 -->
           <property name="configLocation" value="/WEB-INF/ehcache.xml"></property>
     </bean>
ehcache.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
     <diskStore path="java.io.tmpdir" />
     <!-- 多主機負載時,使用EhCache RMI方式的分佈式緩存。見build/prod目錄下每個節點的配置。 -->
     <!-- DefaultCache setting. -->
     <defaultCache maxElementsInMemory="10000"
           memoryStoreEvictionPolicy="LRU" eternal="false" timeToIdleSeconds="300"
           timeToLiveSeconds="300" overflowToDisk="false" diskPersistent="false" />
     <cache name="myCache" overflowToDisk="false" eternal="true"
           diskPersistent="false" maxElementsInMemory="10000"
           memoryStoreEvictionPolicy="LRU" />
</ehcache>

 controller類使用cacheable註解綁定myCache:   
 @Cacheable(value = { "myCache" })
     @GET
     @RequestMapping(value = "/v2/{id}", method = RequestMethod.GET)
     public @ResponseBody Cowboys getOne(@PathVariable("id") String key) {
           Map<String, String> condition = new HashMap<String, String>();
           condition.put("id", key);
           return cowboysDao.getById(condition);
     }
最終結果與第一種一致。

發佈了38 篇原創文章 · 獲贊 51 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章