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

[+]html

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

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

     

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

      

        CachingExecutorExecutor的裝飾者,以加強Executor的功能,使其具備緩存查詢的功能,這裏用到了設計模式中的裝飾者模式,數據庫

       CachingExecutorExecutor的接口的關係以下類圖所示:apache

    

 

2 . MyBatis二級緩存的劃分

MyBatis並非簡單地對整個Application就只有一個Cache緩存對象,它將緩存劃分的更細,便是Mapper級別的,即每個Mapper均可以擁有一個Cache對象,具體以下:設計模式

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

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

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

MyBatisApplication級別的二級緩存細分到Mapper級別,即對於每個Mapper.xml,若是在其中使用了<cache> 節點,則MyBatis會爲這個Mapper建立一個Cache緩存對象,以下圖所示:app

 

注:  上述的每個Cache對象,都會有一個本身所屬的namespace命名空間,而且會將Mapper的 namespace做爲它們的ID;性能

 

 

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

若是你想讓多個Mapper公用一個Cache的話,你可使用<cache-ref namespace="">節點,來指定你的這個Mapper使用到了哪個MapperCache緩存。

 

 

3. 使用二級緩存,必需要具有的條件

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

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

 

[html] view plain copy

 print?

  1. <select id="selectByMinSalary" resultMap="BaseResultMap" parameterType="java.util.Map" useCache="true">  

   

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

   1.  MyBatis支持二級緩存的總開關:全局配置變量參數   cacheEnabled=true

   2. 該select語句所在的Mapper,配置了<cache> 或<cached-ref>節點,而且有效

   3. 該select語句的參數 useCache=true

 

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

      請注意,若是你的MyBatis使用了二級緩存,而且你的Mapperselect語句也配置使用了二級緩存,那麼在執行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緩存中的數據清空;

 

 

6. 寫在後面(關於涉及到的設計模式)

    在二級緩存的設計上,MyBatis大量地運用了裝飾者模式,如CachingExecutor, 以及各類Cache接口的裝飾器。關於裝飾者模式,讀者能夠閱讀相關資料,個人另一篇博文    Java 設計模式 裝飾者模式 供讀者參考。

 

 

 

本文只是講述MyBatis二級緩存的基本原理,關於自定義二級緩存和與第三方內存庫的集成,將在後續的文章中再作討論,敬請關注!

 

 

 

 

做者的話

    本文是《深刻理解mybatis原理》系列的其中一篇,若是您有興趣,請關注該系列的其餘文章~

   以爲本文不錯,順手點個贊哦~~您的鼓勵,是我繼續分享知識的強大動力!

   若是您以爲有不妥或者錯誤的地方,還請您不吝指教!

 

 

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------------

                                                                本文源自  http://blog.csdn.net/luanlouis/,如需轉載,請註明出處,謝謝!

相關文章
相關標籤/搜索