javascript
Springboot + Mybatis + Ehcache
最近在做一個項目,為處理并發(fā)性較差的問題,使用了Mybatis二級緩存
但在多表聯(lián)合查詢的情況下,Mybatis二級緩存是存在著數(shù)據(jù)臟讀的問題的
兩天就是在想辦法解決這個數(shù)據(jù)臟讀的問題
考慮到簡易性、性能、兼容性、可擴展性,我選擇了springboot自帶的 Ehcache 框架來整合解決這個問題
我也是第一次接觸到 Ehcache 這個框架,所以也算從零開始
?
根據(jù)Mybatis二級緩存的特點,我的思路是
每當 增刪改 某張表 , 就清除刷新其關聯(lián)的所有表的 緩存
( 這里可分為兩個大小方向:
在 增刪改 的方法上,做相關的 關聯(lián)清除緩存 操作? ——? 這個就比較細節(jié)化一點,做的修改可能會比較多
在 增刪改方法 所在類的整體上,做相關的 關聯(lián)清除緩存操作? —— 這個我需要做的修改就相對少點,但這樣里面每個方法(包括一些無關緊要的)都會觸發(fā)這個清除緩存操作
都各有利弊 )
?
一路上并不順利,
一開始我嘗試自己看能不能找到比較好的方法,但剛接觸一下子就自己解決也是不太可能的
但有看到一個解決Mybatis二級緩存問題的插件 —— GitHub上 LuanLouis 的 mybatis-enhanced-cache?
但這個project是5年前寫的,而且最近一次更新也只是2年前,現(xiàn)在技術發(fā)展那么快,看到的時候就感覺可能不行
后面自己也下載了下來,mvn install 發(fā)現(xiàn)不成功,缺少ojdbc14的jar包 ,網(wǎng)上說ojdbc14.jar 是收費的,所以中央庫是導不了這個包
看了一些資料說,Oracle安裝目錄里面有,但公司這臺沒裝Oracle ;也有資料說,可以用 ojdbc6 或其他ojdbc代替,我就下載了ojdbc6 和ojdbc8 都試了一下,都能夠解決那個ojdbc jar包的問題,
mybatis-enhanced-cache 插件的jar也成功導入了maven庫和項目中,但導入之后,用的時候卻又發(fā)現(xiàn)報各種錯,就覺得涼了,
本來就是為了簡單快速,才想用別人的插件,所以我不可能自己又去修改這個插件來用,改了又不一定能用!所以使用插件這個方案就只能放棄了
?
后來,又找了網(wǎng)上很多資料,也按很多示例的步驟做了
像各種注解、各種配置什么的,都不知道是和mybatis的注解沖突了,還是我寫的無效
(像網(wǎng)上很多資料說的,mybatis二級緩存是不推薦使用的,至于為什么我還要用,可以看我前面一篇文章——??緩存的設計與使用? ,
所以在方面遇到我這樣問題的應該沒幾個,也就找不到多少資料,只能靠自己)
想了很多可能性,試了一次又一次,想盡量做得簡單點,直接簡單XML配置加注解 ,能夠這樣就好了。
但現(xiàn)實是殘酷的,做了不知多少次的嘗試,還是沒成功,無計可施,最后還是只能放棄這個方案了
?
沒有辦法,就只能選擇最后一種方案了 —— 自己寫代碼,在業(yè)務邏輯層 做處理
這對一無所知的菜鳥,也不容易啊
好在堅持嘗試,最后終于找到解決方案
配置?ehcache.xml
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!-- <ehcache> --> 3 <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:noNamespaceSchemaLocation="ehcache.xsd"> 5 6 <!-- 7 磁盤存儲:將緩存中暫時不使用的對象,轉(zhuǎn)移到硬盤,類似于Windows系統(tǒng)的虛擬內(nèi)存 8 path:指定在硬盤上存儲對象的路徑 9 path可以配置的目錄有: 10 user.home(用戶的家目錄) 11 user.dir(用戶當前的工作目錄) 12 java.io.tmpdir(默認的臨時目錄) 13 ehcache.disk.store.dir(ehcache的配置目錄) 14 絕對路徑(如:d:\\ehcache) 15 查看路徑方法:String tmpDir = System.getProperty("java.io.tmpdir"); 16 --> 17 <diskStore path="java.io.tmpdir" /> 18 19 <!-- 配置提供者 1、peerDiscovery,提供者方式,有兩種方式:自動發(fā)現(xiàn)(automatic)、手動配置(manual) 2、rmiUrls,手動方式時提供者的地址,多個的話用|隔開 --> 20 <!-- <cacheManagerPeerProviderFactory 21 class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" 22 properties="peerDiscovery=manual,rmiUrls=//127.0.0.1:40002/userCache" /> --> 23 <cacheManagerPeerProviderFactory 24 class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory" 25 properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446,timeToLive=255"/> 26 <!-- <cacheManagerPeerProviderFactory 27 class="org.ehcache.distribution.RMICacheManagerPeerProviderFactory" 28 properties="peerDiscovery=automatic, multicastGroupAddress=230.0.0.1, multicastGroupPort=4446,timeToLive=255"/> --> 29 30 <!-- 配置監(jiān)聽器 1、hostName 主機地址 2、port 端口 3、socketTimeoutMillis socket子模塊的超時時間,默認是2000ms --> 31 <!-- <cacheManagerPeerListenerFactory 32 class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory" 33 properties="hostName=127.0.0.1, port=40001, socketTimeoutMillis=2000" /> --> 34 <cacheManagerPeerListenerFactory 35 class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"/> 36 37 38 <!-- 39 defaultCache:默認的緩存配置信息,如果不加特殊說明,則所有對象按照此配置項處理 40 maxElementsInMemory:設置了緩存的上限,最多存儲多少個記錄對象 41 eternal:代表對象是否永不過期 (指定true則下面兩項配置需為0無限期) 42 timeToIdleSeconds:最大的閑置時間 /秒 43 timeToLiveSeconds:最大的存活時間 /秒 44 overflowToDisk:是否允許對象被寫入到磁盤 45 說明:下列配置自緩存建立起600秒(10分鐘)有效 。 46 在有效的600秒(10分鐘)內(nèi),如果連續(xù)120秒(2分鐘)未訪問緩存,則緩存失效。 47 就算有訪問,也只會存活600秒。 48 --> 49 <defaultCache maxElementsInMemory="10000" eternal="false" 50 timeToIdleSeconds="600" timeToLiveSeconds="600" overflowToDisk="true" /> 51 52 <cache name="*.*.*.*.dao.WarnMapper" maxElementsInMemory="10000" eternal="false" 53 timeToIdleSeconds="120" timeToLiveSeconds="300" overflowToDisk="true" /> 54 55 <cache name="*.*.*.*.dao.ProjectMapper" maxElementsInMemory="10000" eternal="false"56 timeToIdleSeconds="120" timeToLiveSeconds="300" overflowToDisk="true" />
57 </ehcache>
配置 application.properties?
1 # Ehcache緩存 2 spring.cache.type=ehcache 3 spring.cache.ehcache.config=classpath:/ehcache.xml業(yè)務邏輯層代碼
1 package *.*.*.common.utils; 2 3 import net.sf.ehcache.Cache; 4 import net.sf.ehcache.CacheManager; 5 6 public class EhcacheUtil { 7 8 // 構(gòu)建一個緩存管理器 9 private static CacheManager cacheManager = CacheManager.newInstance("src/main/resources/ehcache.xml"); 10 11 /** 12 * action 清除相關聯(lián)的緩存 13 * @param cacheName 緩存所在namespace的名稱 14 * @param keys 緩存所在namespace下key的名稱,為空則默認清空所有key 15 * @return 16 */ 17 public static void clearRelatedCache( String cacheName, String[] keys ) { 18 Cache cache = cacheManager.getCache(cacheName) ; 19 if ( cache==null ) { 20 return ; 21 } 22 //若緩存不為空 23 if ( keys==null || keys.length==0 ) { 24 cache.removeAll(); 25 } 26 else { 27 for (String key : keys) { 28 cache.remove(key) ; 29 } 30 } 31 } 32 33 }?
1 @PostMapping("/delete") 2 public Result delete(HttpServletRequest request) { 3 Long projectId = StringUtil.getLong(request.getParameter("id")) ; 4 Project project = projectService.findById(projectId) ; 5 if(project==null) { 6 return ResultGenerator.genFailResult(ResultCode.UNAUTHORIZED, "工程id不正確"); 7 } 8 projectService.deleteById(projectId);; 9 EhcacheUtil.clearRelatedCache(CacheConstants.CACHE_NAMESPACE_WARNMAPPER, null) ; 10 return ResultGenerator.genSuccessResult("刪除成功"); 11 }?
?
共同學習,共同進步,若有補充,歡迎指出,謝謝!
轉(zhuǎn)載于:https://www.cnblogs.com/dengguangxue/p/11276791.html
總結(jié)
以上是生活随笔為你收集整理的Springboot + Mybatis + Ehcache的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: EF 拉姆达 linq if els
- 下一篇: BizTalk开发系列(十二) Sche