1. Mybatis的一級緩存 Mybatis的一級緩存是預設開啟的,你只要搭建一個Mybatis框架,就可以直接使用一級緩存。 一級緩存是SqlSession級別的,通過SqlSession查詢的數據會被緩存,下次使用同一個SqlSession查詢相同的數據,就會從緩存中直接獲取,不會從資料庫重新 ...
1. Mybatis的一級緩存
Mybatis的一級緩存是預設開啟的,你只要搭建一個Mybatis框架,就可以直接使用一級緩存。
一級緩存是SqlSession級別的,通過SqlSession查詢的數據會被緩存,下次使用同一個SqlSession查詢相同的數據,就會從緩存中直接獲取,不會從資料庫重新訪問,減輕資料庫壓力。
條件:
- 同一個SqlSession
- 查詢相同的數據
例子:
-
同一個SqlSession查詢相同的數據
這裡我們通過員工id查詢員工信息,且兩次都是查詢
id=1
的員工通過下麵的日誌信息可以看到,只執行了一次sql語句,但查詢出了兩次員工信息。
所以說第一次是從資料庫中查詢,第二次是從緩存中查詢到的。
-
不同SqlSession查詢相同的數據
使一級緩存失效(滿足2個條件,但不從緩存中找)的2種情況:
-
同一個SqlSession兩次查詢期間執行了任何一次增刪改操作
-
同一個SqlSession兩次查詢期間手動清空了緩存
sqlSession.clearCache();
2. Mybatis的二級緩存
二級緩存是SqlSessionFactory級別,通過同一個SqlSessionFactory創建的SqlSession查詢的結果會被緩存;此後若再次執行相同的查詢語句,結果就會從緩存中獲取。
二級緩存的範圍更大,需要手動開啟。
二級緩存開啟的條件:
-
在核心配置文件中,設置全局配置屬性cacheEnabled="true",預設為true,所以不需要自己設置
-
在Mybatis映射文件中設置標簽:
-
二級緩存必須在SqlSession關閉或提交之後有效
原因:第一次查詢數據只保存在一級緩存中,只有在SqlSession操作完畢(關閉或提交)後,一級緩存中的數據才保存到二級緩存中。
這時候運行代碼會報一個沒有序列化的異常:
-
查詢的數據所轉換的實體類類型必須實現序列化的介面
二級緩存失效的情況:
- 兩次查詢之間執行了任意的增刪改,會使一級和二級緩存同時失效
3. 二級緩存的相關配置
在mapper配置文件中添加的cache標簽可以設置一些屬性:
-
eviction屬性:緩存回收策略,預設的是 LRU。
- LRU(Least Recently Used):最近最少使用的:移除最長時間不被使用的對象。
- FIFO(First in First out):先進先出:按對象進入緩存的順序來移除它們。
- SOFT:軟引用,移除基於垃圾回收器狀態和軟引用規則的對象
- WEAK : 弱引用,更積極地移除基於垃圾收集器狀態和弱引用規則的對象
-
flushInterval屬性:刷新間隔,單位毫秒
預設情況是不設置,也就是沒有刷新間隔,緩存僅僅調用語句時刷新 -
size屬性:引用數目,正整數,一般不去設置它,用預設的就行
代表緩存最多可以存儲多少個對象,太大容易導致記憶體溢出 -
readOnly屬性:只讀, true/false
- true:只讀緩存;會給所有調用者返回緩存對象的相同實例,這些對象不能被修改。這提供了 很重要的性能優勢。
- false:讀寫緩存;會返回緩存對象的拷貝(通過序列化)。這會慢一些,但是安全,因此預設是false。
4. MyBatis緩存查詢的順序
-
先查詢二級緩存,因為二級緩存中可能會有其他程式已經查出來的數據,可以拿來直接使用。
-
如果二級緩存沒有命中,再查詢一級緩存
有小伙伴可能就要說了,二級緩存的範圍更大,二級中包括了一級,二級中都沒有,一級中肯定也沒有啊???
不一定,一級緩存只有關閉或提交後才保存到二級緩存,所以二級緩存中可能也沒有某些一級緩存。
-
如果一級緩存也沒有命中,則查詢資料庫
5. 總結
部分內容來自 B站尚矽谷課程 。老師講得很好,有興趣的可以聽聽。