MyBatis 學習(七)之 緩存

目錄

1 MyBatis 緩存介紹

2 一級緩存

3 二級緩存

3.1 二級緩存介紹

3.2 二級緩存配置

3.3 二級緩存測試

4 參考文檔


1 MyBatis 緩存介紹

????????MyBatis 緩存是 MyBatis 中的一個重要特性,用于提高數據庫查詢的性能。MyBatis 提供了一級緩存和二級緩存兩種類型的緩存機制。

  • 一級緩存:一級緩存(本地緩存)是 MyBatis 中默認的緩存機制,它是 SqlSession 級別的緩存。當使用 SqlSession 執行一次查詢時,查詢到的結果集會存儲在 SqlSession 的緩存中。當使用 SqlSession 再次執行相同的查詢時,它會首先從緩存中獲取結果,而不會再次查詢數據庫。一級緩存是基于事務的,當 SqlSession flush(插入、更新、修改)?或 close 后,該 SqlSession 中的所有 Cache 將被清空

  • 二級緩存:二級緩存是 Mapper 級別的緩存,也稱為 namespace 級別。這意味著無論通過哪個 SqlSession 執行相同的 Mapper 接口操作,都可以訪問到相同的二級緩存數據,即跨 SqlSession 共享同一 Mapper 接口的數據。二級緩存需要手動配置,它可以實現更大范圍的數據共享和更高效的查詢性能。二級緩存也可以配置為使用不同的緩存實現,如 Ehcache、Redis 等

????????MyBatis 緩存的主要作用是減少對數據庫的訪問次數,提高查詢性能。然而,需要注意的是,緩存也會占用內存空間,如果緩存的數據量過大,可能會導致內存溢出的問題。因此,在使用 MyBatis 緩存時,需要根據具體的應用場景和數據量進行合理的配置和調優。

2 一級緩存

????????一級緩存 (local cache),即本地緩存,作用域默認為 SqlSession 。本地緩存不能被關閉,當 SqlSession flush(插入、更新、修改)?或 close 后,該 SqlSession 中的所有 Cache 將被清空。此外,也可以調用 sqlSession.clearCache()?來手動清空本地緩存。

????????在 MyBatis 配置文件中可以通過設置 localCacheScope 參數來改變一級緩存的作用域,它有以下兩種設置:

  • SESSION:?當設置為 SESSION 時,一級緩存將對整個 SqlSession 有效。這意味著在同一個 SqlSession 中執行的查詢會共享同一個緩存。只有當執行 DML 語句(如插入、更新或刪除操作)時,緩存才會被清除。這可以有效地提高相同數據多次查詢的速度,但如果在多個 SqlSession 之間需要同步數據,或者有寫操作發生,可能會出現臟讀的情況
  • STATEMENT:當設置為 STATEMENT 時,一級緩存僅對當前執行的語句有效。這意味著每次語句執行完畢后,緩存就會被清空。這種設置適用于那些可能需要避免臟讀風險的場景,因為它確保了每次查詢都是獨立的,不會受到其他查詢的影響
@Test
public void selectById1() {EmployeeMapper mapper = sqlSessionOne.getMapper(EmployeeMapper.class);// 第一次查詢System.out.println("第一次查詢");Employee employee1 = mapper.selectEmployeeById(1);System.out.println(employee1);// 第二次查詢System.out.println("第二次查詢");Employee employee2 = mapper.selectEmployeeById(1);System.out.println(employee2);// 手動清除本地緩存System.out.println("清除本地緩存");sqlSessionOne.clearCache();// 第三次查詢System.out.println("第三次查詢");Employee employee3 = mapper.selectEmployeeById(1);System.out.println(employee3);}

第一次查詢,從數據庫中查詢數據并將查詢結果保存在本地緩存中

第二次查詢,直接獲取本地緩存的查詢結果

清空本地緩存

第三次查詢,從數據庫中查詢數據

3 二級緩存

3.1 二級緩存介紹

????????MyBatis 的二級緩存是一個更為全局的緩存機制,其作用范圍是 namespace 級別,可以被多個 SqlSession 共享。它的生命周期與應用程序同步,主要用于解決一級緩存不能跨會話共享的問題。

以下是二級緩存的一些詳細介紹:

  • 使用場景:二級緩存適用于多個 SqlSession 需要共享數據的場景。當開啟二級緩存后,MyBatis 會先從二級緩存中獲取數據,如果沒有找到,則會繼續查找一級緩存,最后才訪問數據庫
  • 配置條件:要使用二級緩存,需要滿足以下條件:
    • 全局性地開啟或關閉所有映射器配置文件中已配置的任何二級緩存,可以在 MyBatis 配置文件中通過設置 <setting name="cacheEnabled" value="true"> 來實現
    • 在需要使用二級緩存的映射器配置文件(如 sqlMapper.xml)中添加 <cache/> 配置
    • 使用二級緩存的實體類對象必須是可序列化的,即實現 java.io.Serializable 接口
  • 工作機制:當 SqlSession 對象關閉或提交之后,一級緩存中的數據會被寫入到二級緩存當中。這樣,即使在不同的 SqlSession 之間,也可以訪問到相同的數據集,從而提高了數據訪問的效率
  • 緩存策略:二級緩存的回收策略可以通過設置 <cache> 標簽的屬性來定義,例如 LRU(最近最少使用)策略,用于移除最長時間不被使用的對象

3.2 二級緩存配置

在 MyBatis 配置文件進行設置

<!--開啟二級緩存-->
<settings><setting name="cacheEnabled" value="true"/>
</settings>

在 SQL 映射文件中設置 <cache> 標簽

在 <cache> 標簽中,可以設置多種屬性來定義緩存的行為,例如:

  • eviction:指定緩存回收策略,默認是 LRU(最近最少使用)
    • LRU:最近最少使用:移除最長時間不被使用的對象
    • FIFO:先進先出:按對象進入緩存的順序來移除它們
    • SOFT:軟引用:移除基于垃圾回收器狀態和軟引用規則的對象
    • WEAK:弱引用:更積極地移除基于垃圾收集器狀態和弱引用規則的對象
  • flushInterval:設置緩存刷新間隔,單位為毫秒,默認不清空
  • size:指定二級緩存可以存儲的最大對象數量,默認是 1024
  • readOnly:標記緩存是否為只讀,默認為 false,即可讀可寫,這回慢一點,但是安全
  • type:指定緩存的具體實現類型
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>

注:在 Mapper 接口使用?@CacheNamespace 注解也可以開啟二級緩存

實體類實現 java.io.Serializable 接口

3.3 二級緩存測試

@Test
public void selectAll() {// 不同 sqlSession 對同一 mapper 接口進行操作SqlSession sqlSession1 = sqlSessionFactory.openSession();EmployeeMapper mapper1 = sqlSession1.getMapper(EmployeeMapper.class);SqlSession sqlSession2 = sqlSessionFactory.openSession();EmployeeMapper mapper2 = sqlSession2.getMapper(EmployeeMapper.class);// 通過 sqlSession1 進行第一次查詢List<Employee> employees1 = mapper1.selectAllEmployee();for (Employee employee : employees1) {System.out.println(employee);}// 當 sqlsession 提交、關閉時,二級緩存會有數據//sqlSession1.commit();sqlSession1.clearCache();sqlSession1.close();// 通過 sqlSession2 進行第二次查詢List<Employee> employees2 = mapper2.selectAllEmployee();for (Employee employee : employees2) {System.out.println(employee);}
}

通過 sqlSession1 進行第一次查詢,二級緩存沒有數據

清空 sqlSession1 的一級緩存

sqlSession1 關閉(二級緩存有查詢結果,二級緩存的數據是從一級緩存中來的嗎???)

通過 sqlSession2?進行第二次查詢,從二級緩存中獲得查詢結果,二級緩存命中率 0.5

補充:

禁用二級緩存

????????可以使用 useCache 屬性(這個屬性只有 select 有)來禁用二級緩存,默認為 true,即使用二級緩存,當然也可以通過?@Options(useCache=true) 來設置。

清空一級和二級緩存

????????flushCache 屬性是用來清空一級緩存和二級緩存的。select 中默認為 flushCache=false,insert、delete、update 中默認為 flushCache=true,因為執行數據的增刪改 SQL 語句后,數據庫與緩存數據可能已經不一致,此時緩存已經不能用了,如果不清空緩存則可能出現臟讀的情況。也可以通過?@Options(flushCache=options.FlushCachePolicy.TRUE)?進行設置。

也可以通過實現 cache 接口自定義二級緩存

4 參考文檔

尚硅谷文檔

mybatis 中文文檔 – MyBatis 3 | XML 映射器

Mybatis3詳解(十二)----Mybatis緩存 - 唐浩榮 - 博客園 (cnblogs.com)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/715826.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/715826.shtml
英文地址,請注明出處:http://en.pswp.cn/news/715826.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Git與GitHub:解鎖版本控制的魔法盒子

?? 歡迎大家來訪Srlua的博文&#xff08;づ&#xffe3;3&#xffe3;&#xff09;づ╭?&#xff5e;?? &#x1f31f;&#x1f31f; 歡迎各位親愛的讀者&#xff0c;感謝你們抽出寶貴的時間來閱讀我的文章。 我是Srlua&#xff0c;在這里我會分享我的知識和經驗。&#x…

cetos7 Docker 安裝 gitlab

一、gitlab 簡單介紹和安裝要求 官方文檔&#xff1a;https://docs.gitlab.cn/jh/install/docker.html 1.1、gitlab 介紹 gitLab 是一個用于代碼倉庫管理系統的開源項目&#xff0c;使用git作為代碼管理工具&#xff0c;并在此基礎上搭建起來的Web服務平臺&#xff0c;通過該平…

(六)Dropout抑制過擬合與超參數的選擇--九五小龐

過擬合 即模型在訓練集上表現的很好&#xff0c;但是在測試集上效果卻很差。也就是說&#xff0c;在已知的數據集合中非常好&#xff0c;再添加一些新數據進來效果就會差很多 欠擬合 即模型在訓練集上表現的效果差&#xff0c;沒有充分利用數據&#xff0c;預測準確率很低&a…

笨辦法學 Python3 第五版(預覽)(一)

原文&#xff1a;Learn Python the Hard Way, 5th Edition (Early Release) 譯者&#xff1a;飛龍 協議&#xff1a;CC BY-NC-SA 4.0 模塊 1&#xff1a;Python 入門 練習 0&#xff1a;準備工作 這個練習沒有代碼。這只是你完成的練習&#xff0c;讓你的計算機運行 Python。…

Unity 游戲設計模式:單例模式

本文由 簡悅 SimpRead 轉碼&#xff0c; 原文地址 mp.weixin.qq.com 單例模式 在 C# 游戲設計中&#xff0c;單例模式是一種常見的設計模式&#xff0c;它的主要目的是確保一個類只有一個實例&#xff0c;并提供一個全局訪問點。單例模式在游戲開發中具有以下幾個作用&#xf…

Matlab 機器人工具箱 Link類

文章目錄 1 Link類1.1 機械臂Link類1.2 構造函數1.3 信息/顯示方法1.4 轉換方法1.5 操作方法1.6 測試方法1.7 重載操作1.8 屬性(讀/寫)1.9 例子2 Link.Link2.1 創建機器人連桿對象2.2 OPTIONS2.3 注意2.4 舊語法2.5 例子3 Link的其他函數3.1 Link.A3.2 Link.char3.3 Link.displ…

unity學習(44)——選擇角色菜單——順利收到服務器的數據

本節的思路參考自&#xff0c;內容并不相同&#xff1a;13ARPG網絡游戲編程實踐&#xff08;十三&#xff09;&#xff1a;角色選擇UI及創建面板制作&#xff08;四&#xff09;_嗶哩嗶哩_bilibili 現在的代碼寫在MessageManager.cs中&#xff0c;函數名UserHandler(是從OnMess…

Revit-二開之創建墻-(6)

Revit API窗間墻 protected override Result OnExecute(ExternalCommandData commandData, ref string message, ElementSet elements) {try{// 獲取當前活動的文檔

你是否知道Python的列表翻轉、排序和多維列表

1.reverse() 表示翻轉列表中的元素&#xff0c;不會生成新列表 list1 [2343, 55, 4, 345, 676, 768] list1.reverse() print(list1) # [768, 676, 345, 4, 55, 2343] 2.sort() 對原列表元素進行排序&#xff0c;默認是升序 list1 [2343, 55, 4, 345, 676, 768] list1…

騰訊云幻獸帕魯服務器在Linux和Windows操作系統上的安全性對比如何?哪個更加安全?

騰訊云幻獸帕魯服務器在Linux和Windows操作系統上的安全性對比如何&#xff1f; Linux因其資源利用率高、穩定性和安全性較強而受到許多專業用戶的青睞。這表明在Linux操作系統上&#xff0c;騰訊云可能會更傾向于提供高安全性的服務環境。然而&#xff0c;并沒有直接比較Linu…

MySql--死鎖

一、什么是mysql死鎖? MySQL中的死鎖是指多個事務同時請求對同一資源進行操作(讀或寫),并且由于資源被互斥地鎖定,導致彼此無法繼續進行。當發生死鎖時,MySQL會自動選擇其中一個事務作為死鎖的犧牲者,回滾該事務,并釋放鎖定的資源,從而解除死鎖。 以下是一些處理MyS…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的夜視行人檢測系統(Python+PySide6界面+訓練代碼)

摘要&#xff1a;開發高效的夜視行人檢測系統對于提升夜間安全和監控效能至關重要。本篇博客詳盡介紹了如何利用深度學習技術搭建一個夜視行人檢測系統&#xff0c;并提供了完整的實現代碼。本系統采用了先進的YOLOv8算法&#xff0c;并與YOLOv7、YOLOv6、YOLOv5進行了性能比較…

嵌入式Linux中GPIO設置的一些基本指令和步驟

一、GPIO的介紹 嵌入式Linux中的GPIO&#xff08;General Purpose Input/Output&#xff0c;通用輸入/輸出&#xff09;是一種常用的接口&#xff0c;允許開發者直接控制硬件設備的某些引腳&#xff0c;進行諸如LED控制、傳感器讀取、設備狀態監測等任務。 二、設置步驟和示例…

藍橋杯復習之二分法與前綴和

題目&#xff1a;最佳牛圍欄 題目鏈接&#xff1a;https://www.acwing.com/problem/content/104/ 題意&#xff1a;農夫約翰的農場由 N 塊田地組成&#xff0c;每塊地里都有一定數量的牛&#xff0c;其數量不會少于 1 頭&#xff0c;也不會超過 2000 頭。 約翰希望用圍欄將一…

GEE學習筆記003-訪問asset文件

在 Google Earth Engine (GEE) 中&#xff0c;您可以通過將 asset 文件的路徑直接寫入代碼中來引用它。這是通過在文件路徑前加上 ee.Image() 或 ee.FeatureCollection() 來實現的&#xff0c;具體取決于您想要導入的是影像還是矢量數據。 以下是導入 asset 文件并將其直接寫入…

第四十四天| 卡爾網 52. 攜帶研究材料、518. 零錢兌換 II、377. 組合總和 Ⅳ

01背包問題卡爾網 52. 攜帶研究材料 題目鏈接&#xff1a;52 攜帶研究材料 題干&#xff1a;小明是一位科學家&#xff0c;他需要參加一場重要的國際科學大會&#xff0c;以展示自己的最新研究成果。他需要帶一些研究材料&#xff0c;但是他的行李箱空間有限。這些研究材料包括…

centos7安裝夜鶯

一、前期準備 1.1.關閉防火墻&#xff0c;SELINUX systemctl stop firewalld.service systemctl disable firewalld.service setenforce 0 sed -i "s/SELINUXenforcing/SELINUXdisabled/g" /etc/selinux/config查看狀態 systemctl status firewalld systemctl sta…

Vue開發實例(三)項目引入Element-UI

項目引入Element-UI 一、引入Element-UI二、注冊組件1、vue2使用element-ui2、vue3使用element-ui 三、使用Element組件1、輕微改造2、驗證element是否生效 一、引入Element-UI npm i element-ui --save npm install element-ui -S等待安裝完成 二、注冊組件 1、vue2使用ele…

【Leetcode每日一題】前綴和(難度?)(25)

1. 題目解析 題目鏈接&#xff1a;DP34 【模板】前綴和 這個問題的理解其實相當簡單&#xff0c;只需看一下示例&#xff0c;基本就能明白其含義了。 核心在于計算題目所給區間數組元素和返回即可。 2. 算法原理 為了提高計算效率&#xff0c;我們可以預先計算出一個「前綴…

在github的README.md中插入視頻;在github的README.md中添加gif演示動畫

最近需要再github中上傳項目的源代碼&#xff0c;應導師的要求&#xff0c;需要再README中加入對實驗視頻的展示&#xff0c;但是github的README.md其實就是一個markdown文件&#xff0c;據我的理解這個文件里應該無法直接插入視頻吧&#xff1f;&#xff08;如果后續有辦法直接…