MyBatis筆記(七)
1. 簡介
- 什麼是快取?
- 存在記憶體中的臨時數據
- 將用戶經常查詢的數據存放在快取(記憶體)中,用戶取查詢就不用從磁碟上(關係型資料庫數據文件)查詢,從快取中查詢,從而提高查詢效率,解決了高並發系統的性能問題
- 為什麼使用快取?
- 減少和資料庫交互的次數
- 什麼樣的數據能使用快取?
- 經常查詢並且不經常改變的數據
2. MyBatis快取
- MyBatis包含一個非常強大的查詢快取特性,它可以非常方便地訂製和配置快取,快取可以極大地提升查詢效率
- MyBatis系統中默認定義了兩級快取:一級快取和二級快取
- 默認情況下,只有一級快取開啟(SqlSession級別地快取,也稱為本地快取)
- 二級快取需要手動開啟和配置,它是基於namespace級別的快取
- 為了提高擴展性,MyBatis定義了快取介面Cache,我們可以通過實現Cache介面來自定義二級快取
3. 一級快取
-
一級快取是默認開啟的
-
一級快取也叫本地快取:
- 與資料庫同一次會話期間查到的數據會放在本地快取中
- 以後如果要獲取相同的數據,直接從快取中拿,不用再去查詢資料庫了
-
一級快取是SqlSession級別的快取,是一直開啟的,我們關閉不了它
-
一級快取失效結果:查詢相同的數據仍需再次發起一次查詢請求
-
一級快取失效的四種情況:
-
sqlSession不同:每個sqlSession中的快取相互獨立
-
sqlSession相同,查詢條件不同
-
sqlSession相同,兩次查詢之間執行了增刪改操作
-
sqlSession相同,手動清楚一級快取(使用謝列語句可以清除快取)
session.clearCache();
-
-
一級快取就是一個map
4. 二級快取
-
二級快取也叫全局快取,一級快取作用域太低了,所以產生了二級快取
-
基於
namespace
級別的快取,一個名稱空間對應一個二級快取 -
工作機制:
- 一個會話查詢一個數據,這個數據就會被放在當前會話的一級快取中。如果當前會話關閉了,這個會話對應的一級快取就沒了。但是我們想要的是會話關閉了,一級快取中的數據被保存到二級快取中,新的會話查詢資訊,就可以從二級快取中獲取內容,不同mapper查出的數據會藏在自己對應的快取(map)中
-
開啟二級快取步驟:
-
開啟全局快取
mybatis-config.xml
<setting name="cacheEnabled" value="true"/>
-
去每個mapper.xml中配置使用二級快取
<cache/> 官方示例=====>查看官方文檔 <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> <!-- 這個更高級的配置創建了一個 FIFO 快取,每隔 60 秒刷新,最多可以存儲結果對象或列表的 512 個引用,而且返回的對象被認為是只讀的,因此對它們進行修改可能會在不同執行緒中的調用者產生衝突。 -->
-
-
總結:
- 只要開啟了二級快取,我們在同一個mapper中的查詢,可以在二級快取中拿到數據
- 查出的數據都會默認先放在一級快取中
- 只有會話提交或者關閉以後,一級快取中的數據才會轉到二級快取中
5. 快取原理
-
快取原理圖
6. EhCache
-
第三方快取的實現 —— EhCache
-
EhCache是一種廣泛使用的Java分故事快取,用於通用快取
-
在應用程式中使用EhCache
-
引入依賴jar包
<!-- //mvnrepository.com/artifact/org.mybatis.caches/mybatis-ehcache --> <dependency> <groupId>org.mybatis.caches</groupId> <artifactId>mybatis-ehcache</artifactId> <version>1.1.0</version> </dependency>
-
在mapper配置文件中使用對應的快取即可
<mapper namespace = 「org.acme.FooMapper」 > <cache type = 「org.mybatis.caches.ehcache.EhcacheCache」 /> </mapper>
-
編寫ehcache.xml文件,如果在載入時未找到
/ehcache.xml
資源或者出現問題,則將使用默認配置<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="//www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="//ehcache.org/ehcache.xsd" updateCheck="false"> <!-- diskStore:為快取路徑,ehcache分為記憶體和磁碟兩級,此屬性定義磁碟的快取位置。參數解釋如下: user.home – 用戶主目錄 user.dir – 用戶當前工作目錄 java.io.tmpdir – 默認臨時文件路徑 --> <diskStore path="./tmpdir/Tmp_EhCache"/> <defaultCache eternal="false" maxElementsInMemory="10000" overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="1800" timeToLiveSeconds="259200" memoryStoreEvictionPolicy="LRU"/> <cache name="cloud_user" eternal="false" maxElementsInMemory="5000" overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="1800" timeToLiveSeconds="1800" memoryStoreEvictionPolicy="LRU"/> <!-- defaultCache:默認快取策略,當ehcache找不到定義的快取時,則使用這個快取策略。只能定義一個。 --> <!-- name:快取名稱。 maxElementsInMemory:快取最大數目 maxElementsOnDisk:硬碟最大快取個數。 eternal:對象是否永久有效,一但設置了,timeout將不起作用。 overflowToDisk:是否保存到磁碟,當系統當機時 timeToIdleSeconds:設置對象在失效前的允許閑置時間(單位:秒)。僅當eternal=false對象不是永久有效時使用,可選屬性,默認值是0,也就是可閑置時間無窮大。 timeToLiveSeconds:設置對象在失效前允許存活時間(單位:秒)。最大時間介於創建時間和失效時間之間。僅當eternal=false對象不是永久有效時使用,默認是0.,也就是對象存活時間無窮大。 diskPersistent:是否快取虛擬機重啟期數據 Whether the disk store persists between restarts of the Virtual Machine. The default value is false. diskSpoolBufferSizeMB:這個參數設置DiskStore(磁碟快取)的快取區大小。默認是30MB。每個Cache都應該有自己的一個緩衝區。 diskExpiryThreadIntervalSeconds:磁碟失效執行緒運行時間間隔,默認是120秒。 memoryStoreEvictionPolicy:當達到maxElementsInMemory限制時,Ehcache將會根據指定的策略去清理記憶體。默認策略是LRU(最近最少使用)。你可以設置為FIFO(先進先出)或是LFU(較少使用)。 clearOnFlush:記憶體數量最大時是否清除。 memoryStoreEvictionPolicy:可選策略有:LRU(最近最少使用,默認策略)、FIFO(先進先出)、LFU(最少訪問次數)。 FIFO,first in first out,這個是大家最熟的,先進先出。 LFU, Less Frequently Used,就是上面例子中使用的策略,直白一點就是講一直以來最少被使用的。如上面所講,快取的元素有一個hit屬性,hit值最小的將會被清出快取。 LRU,Least Recently Used,最近最少使用的,快取的元素有一個時間戳,當快取容量滿了,而又需要騰出地方來快取新的元素的時候,那麼現有快取元素中時間戳離當前時間最遠的元素將被清出快取。 --> </ehcache>
-