1. 程式人生 > >分享知識-快樂自己:Mybatis快取機制

分享知識-快樂自己:Mybatis快取機制

論快取機制:

1):mybatis 提供了快取機制減輕資料庫壓力,提高資料庫效能。 2):mybatis 的快取分為兩級:一級快取、二級快取 3):一級快取是SqlSession級別的快取,快取的資料只在SqlSession內有效。 4):二級快取是mapper級別的快取,同一個namespace公用這一個快取,所以對 SqlSession是共享的  

一級快取:

mybatis 的一級快取是SqlSession級別的快取,在操作資料庫的時候需要先建立SqlSession會話物件,在物件中有一個HashMap用於儲存快取資料,此HashMap是當前會話物件私有的,別的SqlSession會話物件無法訪問。

具體流程:

 

1).第一次執行select完畢會將查到的資料寫入SqlSession內的HashMap中快取起來

 

2).第二次執行select會從快取中查資料,如果select相同切傳引數一樣,那麼就能從快取中返回資料,不用去資料庫了,從而提高了效率   注意事項: 1):一級快取的作用域是SqlSession範圍的,當在同一個SqlSession中執行兩次相同的 sql 語句時,第一次執行完畢會將資料庫中查詢的資料寫到快取(記憶體)中,   第二次查詢時會從快取中獲取資料,不再去底層進行資料庫查詢,從而提高了查詢效率。需要注意的是:如果SqlSession執行了DML操作(insert、update、delete),
  並執行commit()操作,mybatis則會清空SqlSession中的一級快取,這樣做的目的是為了保證快取資料中儲存的是最新的資訊,避免出現髒讀現象。   2):當一個SqlSession結束後那麼他裡面的一級快取也就不存在了,mybatis預設是開啟 一級快取,不需要配置   3):mybatis的快取是基於[namespace:sql語句:引數]來進行快取的,意思就是, SqlSession的HashMap儲存快取資料時,是使用[namespace:sql:引數]作為key,查 詢返回的語句作為value儲存的。
  例:-1242243203:1146242777:winclpt.bean.userMapper.getUser:0:2147483647:select * from user where id=?:19

二級快取:

二級快取是mapper級別的快取,也就是同一個namespace的mappe.xml,當多個SqlSession使用同一個Mapper操作資料庫的時候,得到的資料會快取在同一個二級快取區域,二級快取預設是沒有開啟的。

需要在setting全域性引數中配置開啟二級快取

conf.xml:

<settings>
        <setting name="cacheEnabled" value="true"/>預設是false:關閉二級快取
<settings>

在userMapper.xml中配置:

<!--在當前內部Mapper中開啟二級快取-->
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>
<!--引用全域性快取配置檔案-->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
當前 mapper下所有語句開啟二級快取 這裡配置了一個LRU快取,並每隔60秒重新整理,最大儲存512個物件,而卻返回的物件是隻讀的。   cache元素用來開啟當前mapper的namespace下的二級快取,該元素的屬性設定如下: flushInterval:   重新整理間隔,可以被設定為任意的正整數,而且它們代表一個合理的毫秒形式的時間段,預設情況下是不設定的,也就是沒有重新整理間隔,快取僅僅呼叫語句時重新整理。   size:   快取數目,可以被設定為任意正整數,要記住你的快取物件數目和你執行環境可用記憶體資源數目,預設值是1024.   readOnly:   只讀,屬性可以被設定為true或false,只讀的快取會給所有呼叫者返回快取物件的相同例項,因此這些物件不能被修改。   這提供了很重要的效能優勢,可讀寫的快取會返回快取物件的拷貝(通過序列化),這會慢一些,但是安全,因此預設是false。   eviction:收回策略,預設為LRU,有如下幾種:   LRU:最近最少使用的策略,移除最長時間不被使用的物件。   FIFO:先進先出策略,按物件進入快取的順序來移除它們。   SOFT:軟引用策略,移除基於垃圾回收器狀態和軟引用規則的物件。   WEAK:弱引用策略,更積極地移除基於垃圾收集器狀態和弱引用規則的物件。   若想禁用當前select語句的二級快取,新增useCache="false"修改如下:
<select id="getCountByName" parameterType="java.util.Map" 
resultType="INTEGER" statementType="CALLABLE" useCache="false">
具體流程:   1).當一個sqlseesion執行了一次select後,在關閉此session的時候,會將查詢結果快取到二級快取   2).當另一個sqlsession執行select時,首先會在他自己的一級快取中找,如果沒找到,就回去二級快取中找,找到了就返回,就不用去資料庫了,從而減少了資料庫壓力提高了效能。   注意事項一:   1).如果SqlSession執行了DML操作(insert、update、delete),並commit了,那麼 mybatis就會清空當前mapper快取中的所有快取資料,這樣可以保證快取中的存的數 據永遠和資料庫中一致,避免出現髒讀     2).mybatis的快取是基於[namespace:sql語句:引數]來進行快取的,意思就是SqlSession 的HashMap儲存快取資料時,是使用[namespace:sql:引數]作為key,查詢返回的語 句作為value儲存的。   注意事項二:   1):使用二級快取時,與查詢結果對映的java物件必須實現java.io.Serializable介面的序 列化和反序列化操作,如果存在父類,其成員都需要實現序列化介面,     實現序列化 介面是為了對快取資料進行序列化和反序列化操作,因為二級快取資料儲存介質多 種多樣,不一定在記憶體,有可能是硬碟或者遠端伺服器。   例:-1242243203:1146242777:winclpt.bean.userMapper.getUser:0:2147483647:select * from user where id=?:19

全域性配置檔案:

ehcache.xml:

 

 

<ehcache>

    <!--臨時檔案目錄  可以自己設定-->
    <diskStore path="java.io.tmpdir"/>

    <!--
    maxElementsInMemory:在記憶體中最大的儲存量
    eternal:是否在記憶體中永遠不銷燬
    timeToIdleSeconds:在快取中閒置多少時間之後銷燬,預設單位是S
    timeToLiveSeconds:在快取中存活多少時間之後銷燬,無論是否有人使用,預設單位是S
    overflowToDisk:當快取滿的時候是否儲存到磁碟中
    diskPersistent:磁碟中的檔案是否永久儲存
    diskExpiryThreadIntervalSeconds:檢測執行緒執行時間間隔!預設單位是S


    *******************************************************
    memoryStoreEvictionPolicy  :  快取清理策略
    1.LRU (least recently  used) 最近最少使用
       每個快取的元素都有一個時間戳,當快取容量滿的時候,需要騰出來新位置給新快取元素,
       這時候,會比較時間戳然後刪除符合條件的快取元素

    2.LFU (least frequently used )最少使用
         一直以來最少使用的快取元素,快取元素中有一個hit值,hit值最少的將會清除!

    3.FIFO(first in  first out)  先進先出
    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            overflowToDisk="true"
            diskPersistent="false"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU"
    />
</ehcache>

 

 

參考:

1): https://blog.csdn.net/zouxucong/article/details/68947052
2): https://www.cnblogs.com/winclpt/articles/7511672.html

 

demo:

https://note.youdao.com/share/?id=80eda2335aa3c7605116c24ac6e03b48&type=note#/

END:

  對於MyBatis 快取的內容僅做了解即可,因為面對一定規模的資料量,內建的Cache 方式就派不上用場了;並且對查詢結果集做快取並不是MyBatis 框架擅長的,它專心做的應該是SQL 對映。   所以採用 OSCache 、Memcached 等專門的快取伺服器來做更為合理。