1. 程式人生 > >《深入理解mybatis原理7》 MyBatis的二級緩存的設計原理

《深入理解mybatis原理7》 MyBatis的二級緩存的設計原理

data 是否 cat sch 定義 劃分 sel 博文 算法

《深入理解mybatis原理》 MyBatis的二級緩存的設計原理

MyBatis的二級緩存是Application級別的緩存,它可以提高對數據庫查詢的效率,以提高應用的性能。本文將全面分析MyBatis的二級緩存的設計原理。

1.MyBatis的緩存機制整體設計以及二級緩存的工作模式

技術分享圖片

如上圖所示,當開一個會話時,一個SqlSession對象會使用一個Executor對象來完成會話操作,MyBatis的二級緩存機制的關鍵就是對這個Executor對象做文章。如果用戶配置了"cacheEnabled=true",那麽MyBatis在為SqlSession對象創建Executor對象時,會對Executor對象加上一個裝飾者:CachingExecutor,這時SqlSession使用CachingExecutor對象來完成操作請求。CachingExecutor對於查詢請求,會先判斷該查詢請求在Application級別的二級緩存中是否有緩存結果,如果有查詢結果,則直接返回緩存結果;如果緩存中沒有,再交給真正的Executor對象來完成查詢操作,之後CachingExecutor會將真正Executor返回的查詢結果放置到緩存中,然後在返回給用戶。

技術分享圖片

CachingExecutor是Executor的裝飾者,以增強Executor的功能,使其具有緩存查詢的功能,這裏用到了設計模式中的裝飾者模式.

CachingExecutor和Executor的接口的關系如下類圖所示:

技術分享圖片

2 . MyBatis二級緩存的劃分

MyBatis並不是簡單地對整個Application就只有一個Cache緩存對象,它將緩存劃分的更細,即是Mapper級別的,即每一個Mapper都可以擁有一個Cache對象,具體如下:

a.為每一個Mapper分配一個Cache緩存對象(使用<cache>節點配置);

b.多個Mapper共用一個Cache緩存對象(使用<cache-ref>節點配置);

b.多個Mapper共用一個Cache緩存對象(使用<cache-ref>節點配置) 如果你想讓多個Mapper公用一個Cache的話,你可以使用<cache-ref namespace="">節點,來指定你的這個Mapper使用到了哪一個Mapper的Cache緩存。

技術分享圖片

3.使用二級緩存,必須要具備的條件

MyBatis對二級緩存的支持粒度很細,它會指定某一條查詢語句是否使用二級緩存。

雖然在Mapper中配置了<cache>,並且為此Mapper分配了Cache對象,這並不表示我們使用Mapper中定義的查詢語句查到的結果都會放置到Cache對象之中,我們必須指定Mapper中的某條選擇語句是否支持緩存,即如下所示,在<select> 節點中配置useCache="true",Mapper才會對此Select的查詢支持緩存特性,否則,不會對此Select查詢,不會經過Cache緩存。如下所示,Select語句配置了useCache="true",則表明這條Select語句的查詢會使用二級緩存。

 <select id="selectByMinSalary" resultMap="BaseResultMap" parameterType="java.util.Map" useCache="t       rue">

總之,要想使某條Select查詢支持二級緩存,你需要保證:

  1.  MyBatis支持二級緩存的總開關:全局配置變量參數   cacheEnabled=true
?
2. 該select語句所在的Mapper,配置了<cache> 或<cached-ref>節點,並且有效
?
3. 該select語句的參數 useCache=true

4.一級緩存和二級緩存的使用順序

請註意,如果你的MyBatis使用了二級緩存,並且你的Mapper和select語句也配置使用了二級緩存,那麽在執行select查詢的時候,MyBatis會先從二級緩存中取輸入,其次才是一級緩存,即MyBatis查詢數據的順序是:

     二級緩存    ———> 一級緩存——> 數據庫

5.二級緩存實現的選擇

MyBatis對二級緩存的設計非常靈活,它自己內部實現了一系列的Cache緩存實現類,並提供了各種緩存刷新策略如LRU,FIFO等等;另外,MyBatis還允許用戶自定義Cache接口實現,用戶是需要實現org.apache.ibatis.cache.Cache接口,然後將Cache實現類配置在<cache type="">節點的type屬性上即可;除此之外,MyBatis還支持跟第三方內存緩存庫如Memecached的集成,總之,使用MyBatis的二級緩存有三個選擇:

1.MyBatis自身提供的緩存實現;
?
2. 用戶自定義的Cache接口實現;
?
3.跟第三方內存緩存庫的集成;

6.MyBatis自身提供的二級緩存的實現

MyBatis自身提供了豐富的,並且功能強大的二級緩存的實現,它擁有一系列的Cache接口裝飾者,可以滿足各種對緩存操作和更新的策略。

MyBatis定義了大量的Cache的裝飾器來增強Cache緩存的功能,如下類圖所示。

對於每個Cache而言,都有一個容量限制,MyBatis各供了各種策略來對Cache緩存的容量進行控制,以及對Cache中的數據進行刷新和置換。MyBatis主要提供了以下幾個刷新和置換策略:

LRU:(Least Recently Used),最近最少使用算法,即如果緩存中容量已經滿了,會將緩存中最近做少被使用的緩存記錄清除掉,然後添加新的記錄;

FIFO:(First in first out),先進先出算法,如果緩存中的容量已經滿了,那麽會將最先進入緩存中的數據清除掉;

Scheduled:指定時間間隔清空算法,該算法會以指定的某一個時間間隔將Cache緩存中的數據清空;

技術分享圖片

  1. 寫在後面(關於涉及到的設計模式) 在二級緩存的設計上,MyBatis大量地運用了裝飾者模式,如CachingExecutor, 以及各種Cache接口的裝飾器。關於裝飾者模式,讀者可以閱讀相關資料,我的另外一篇博文 Java 設計模式 裝飾者模式 供讀者參考。

《深入理解mybatis原理7》 MyBatis的二級緩存的設計原理