【Mybatis學習筆記】—— 【五】緩存機制

需要更好的閱讀的體驗請移步 👉 小牛肉的個人博客 👈



MyBatis 包含一個非常強大的查詢緩存特性,它可以非 常方便地配置和定製。緩存可以極大的提升查詢效率。
MyBatis系統中默認定義了兩級緩存:一級緩存和二級緩存。

  • 默認情況下,只有一級緩存(SqlSession級別的緩存, 也稱爲本地緩存)開啓。
  • 二級緩存需要手動開啓和配置,他是基於namespace級 別的緩存。(也稱爲全局緩存)
  • 爲了提高擴展性。MyBatis定義了緩存接口Cache。我們 可以通過實現Cache接口來自定義二級緩存

1. 一級緩存(本地緩存)

一級緩存(本地緩存):sqlSession 級別的緩存

  • 一級緩存是一直開啓的;
  • SqlSession 級別的一個Map
  • 與數據庫同一次會話期間查詢到的數據會放在本地緩存中。以後如果需要獲取相同的數據,直接從緩存中拿,沒必要再去查詢數據庫;

一級緩存失效情況(沒有使用到當前一級緩存的情況,還需要再向數據庫重新發出sql語句進行查詢):

  • sqlSession不同
  • sqlSession相同,查詢條件不同.(當前一級緩存中還沒有這個數據)
  • sqlSession相同,兩次查詢之間執行了增刪改操作(因爲這次增刪改可能對當前數據有影響)
  • sqlSession相同,手動清除了一級緩存(緩存清空) openSession.clearCache();

2. 二級緩存(全局緩存)

二級緩存(全局緩存):基於namespace級別的緩存,一個namespace對應一個二級緩存 <mapper namespace="com.smallbeef.mybatis.dao.EmployeeMapper">

工作機制:

  • 一個會話,查詢一條數據,這個數據就會被放在當前會話的一級緩存中;

  • 如果會話關閉,一級緩存中的數據會被保存到二級緩存中;新的會話查詢信息,就可以參照二級緩存中的內容;(二級緩存只有在 SqlSession 關閉或提交之後纔會生效

  • 不同namespace查出的數據會放在自己對應的緩存中(map)

使用:

  • (二級緩存默認不開啓,需要手動配置 )在全局配置文件中 開啓全局二級緩存配置:
<settings>	
	<!--顯式的指定每個我們需要更改的配置的值,即使他是默認的。防止版本更新帶來的問題  -->
	<setting name="cacheEnabled" value="true"/>
</settings>
  • mapper.xml 中配置使用二級緩存:<cache></cache>
<mapper namespace="com.smallbeef.mybatis.dao.EmployeeMapper">
	<cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024"></cache>

cache標籤的屬性:

eviction : 緩存的回收策略:

  • LRU (默認) – 最近最少使用的:移除最長時間不被使用的對象。
  • FIFO – 先進先出:按對象進入緩存的順序來移除它們。
  • SOFT – 軟引用:移除基於垃圾回收器狀態和軟引用規則的對象。
  • WEAK – 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的對象。

flushInterval :緩存刷新間隔
緩存多長時間清空一次,默認不清空。單位是毫秒

readOnly : 是否只讀:

  • true:只讀:mybatis認爲所有從緩存中獲取數據的操作都是隻讀操作,不會修改數據。
    mybatis爲了加快獲取速度,直接就會將數據在緩存中的引用交給用戶。不安全,速度快
  • false:非只讀 (默認):mybatis覺得獲取的數據可能會被修改。
    mybatis會利用序列化&反序列的技術克隆一份新的數據給你。安全,速度慢

size :緩存存放多少元素;代表緩存最多可以存儲多少個對象,太大容易導致內存溢出

type :指定自定義緩存的全類名;(默認就是 namespace 的名稱)

  • 注意: POJO需要實現序列化接口
public class Employee implements Serializable{

}

3. 緩存相關設置

和緩存有關的設置/屬性:

  • cacheEnabled=true:開啓二級緩存
    false:關閉緩存(二級緩存關閉)(一級緩存仍然可用)

  • 每個 select 標籤都有 useCache="true" (默認)
    配置這個select是否使用二級緩存。一級緩存一直是使用的

  • 每個增刪改標籤默認 flushCache="true":sql執行以後,會同時清空一級和二級緩存。
    查詢標籤默認 flushCache="false"

  • sqlSession.clearCache(); 清除當前session的一級緩存;

  • 當在某一個作用域 (一級緩存Session/二級緩存 namespace) 進行了增刪改 操作後,默認該作用域下所有 select 中的緩存將被 clear。

4. Mybatis 的緩存原理

5. 第三方緩存 EhCache 整合

EhCache 是一個純Java的進程內緩存框架,具有快速、精 乾等特點,是Hibernate中默認的CacheProvider。

整合步驟如下:

導入 ehcache 包,以及Mybatis整合包,日誌包

  • ehcache-core-2.6.8.jar
  • mybatis-ehcache-1.0.3.jar
  • slf4j-api-1.6.1.jar
  • slf4j-log4j12-1.6.2.jar

編寫ehcache.xml配置文件

該配置文件放在 conf 文件夾下,和 全局配置配置文件 爲同級目錄

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 <!-- 磁盤保存路徑 -->
 <diskStore path="D:\44\ehcache" />
 
 <defaultCache 
   maxElementsInMemory="10000" 
   maxElementsOnDisk="10000000"
   eternal="false" 
   overflowToDisk="true" 
   timeToIdleSeconds="120"
   timeToLiveSeconds="120" 
   diskExpiryThreadIntervalSeconds="120"
   memoryStoreEvictionPolicy="LRU">
 </defaultCache>
</ehcache>
 

屬性說明:

  • diskStore:指定數據在磁盤中的存儲位置。
  • defaultCache:當藉助CacheManager.add(“demoCache”)創建Cache時,EhCache便會採用< defalutCache />指定的的管理策略

以下屬性是必須的:

  • maxElementsInMemory - 在內存中緩存的element的最大數目
  • maxElementsOnDisk - 在磁盤上緩存的element的最大數目,若是0表示無窮大
  • eternal - 設定緩存的elements是否永遠不過期。如果爲true,則緩存的數據始終有效,如果爲false那麼還要根據timeToIdleSeconds,timeToLiveSeconds判斷
  • overflowToDisk - 設定當內存緩存溢出的時候是否將過期的element緩存到磁盤上

以下屬性是可選的:

  • timeToIdleSeconds - 當緩存在EhCache中的數據前後兩次訪問的時間超過timeToIdleSeconds的屬性取值時,這些數據便會刪除,默認值是0,也就是可閒置時間無窮大
  • timeToLiveSeconds - 緩存element的有效生命期,默認是0.,也就是element存活時間無窮大
  • diskSpoolBufferSizeMB 這個參數設置DiskStore(磁盤緩存)的緩存區大小.默認是30MB.每個Cache都應該有自己的一個緩衝區.
  • diskPersistent - 在VM重啓的時候是否啓用磁盤保存EhCache中的數據,默認是false。
  • diskExpiryThreadIntervalSeconds - 磁盤緩存的清理線程運行間隔,默認是120秒。每個120s,相應的線程會進行一次EhCache中數據的清理工作
  • memoryStoreEvictionPolicy - 當內存緩存達到最大,有新的element加入的時候, 移除緩存中element的策略。默認是LRU(最近最少使用),可選的有LFU(最不常使用)和FIFO(先進先出)

mapper 中配置 cache標籤

<mapper namespace="com.smallbeef.mybatis.dao.EmployeeMapper">
	<cache type= "org.mybatis.caches.ehcache.EhcacheCache"></cache> 

若想在命名空間中共享相同的緩存配置和實例。 可以使用 cache-ref 元素來引用另外一個緩存。

<mapper namespace="com.smallbeef.mybatis.dao.DepartmentMapper">
	<cache-ref namespace="com.atguigu.mybatis.dao.EmployeeMapper"/>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章