深入解析Mybatis中緩存機(jī)制及優(yōu)缺點(diǎn)
MyBatis 提供了完善的緩存機(jī)制,用于減少了數(shù)據(jù)庫訪問次數(shù),提升查詢性能。其緩存體系分為一級(jí)緩存(本地緩存)和二級(jí)緩存(全局緩存),兩者配合使用形成了 MyBatis 的緩存體系。
一、MyBatis 緩存機(jī)制詳解
1. 一級(jí)緩存(Local Cache)
- 作用范圍:SqlSession 級(jí)別(即同一個(gè)數(shù)據(jù)庫會(huì)話內(nèi)有效)。
- 實(shí)現(xiàn)原理:默認(rèn)開啟,無需配置。MyBatis 在 SqlSession 內(nèi)部維護(hù)一個(gè) HashMap 作為緩存容器,鍵為
CacheKey(由 SQL 語句、參數(shù)、RowBounds、環(huán)境等信息生成),值為查詢結(jié)果。 - 生命周期:與 SqlSession 一致,當(dāng) SqlSession 關(guān)閉(
close())或提交(commit())、回滾(rollback())時(shí),一級(jí)緩存會(huì)被清空。 - 觸發(fā)場景:
- 同一 SqlSession 中,執(zhí)行相同的查詢(SQL 語句、參數(shù)、分頁等完全一致),會(huì)直接從緩存獲取結(jié)果,不執(zhí)行 SQL。
- 若 SqlSession 中執(zhí)行了增刪改操作(
insert/update/delete),MyBatis 會(huì)自動(dòng)清空一級(jí)緩存,避免臟數(shù)據(jù)。
2. 二級(jí)緩存(Global Cache)
- 作用范圍:Mapper 接口級(jí)別(跨 SqlSession 共享,多個(gè) SqlSession 可共享同一 Mapper 的緩存)。
- 實(shí)現(xiàn)原理:默認(rèn)關(guān)閉,需手動(dòng)開啟。開啟后,MyBatis 會(huì)為每個(gè) Mapper 接口創(chuàng)建一個(gè)緩存對(duì)象(可自定義緩存實(shí)現(xiàn),如 Redis、EhCache 等),查詢結(jié)果會(huì)先存入一級(jí)緩存,當(dāng) SqlSession 關(guān)閉時(shí),一級(jí)緩存的數(shù)據(jù)會(huì)被刷入二級(jí)緩存。
- 開啟方式:
- 在 MyBatis 配置文件中開啟全局二級(jí)緩存(默認(rèn)
true,可省略):
xml
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>- 在 Mapper 接口或 XML 中聲明使用二級(jí)緩存:
- XML 方式:在 Mapper.xml 中添加 `<cache/>` 標(biāo)簽。 - 注解方式:在 Mapper 接口上添加 `@CacheNamespace` 注解。
- 緩存策略:可通過
<cache>標(biāo)簽的屬性配置,如eviction(回收策略,如 LRU、FIFO)、flushInterval(自動(dòng)刷新時(shí)間)、size(最大緩存條目)、readOnly(是否只讀)等。 - 觸發(fā)清空:當(dāng) Mapper 中執(zhí)行增刪改操作時(shí),MyBatis 會(huì)清空該 Mapper 對(duì)應(yīng)的二級(jí)緩存。
3. 緩存執(zhí)行順序
查詢數(shù)據(jù)時(shí),MyBatis 會(huì)按以下順序查找緩存:二級(jí)緩存 → 一級(jí)緩存 → 數(shù)據(jù)庫
- 若二級(jí)緩存命中,直接返回結(jié)果。
- 若二級(jí)緩存未命中,查詢一級(jí)緩存,命中則返回。
- 若一級(jí)緩存也未命中,執(zhí)行 SQL 查詢數(shù)據(jù)庫,結(jié)果依次存入一級(jí)緩存和二級(jí)緩存(當(dāng) SqlSession 關(guān)閉時(shí))。
二、MyBatis 緩存的優(yōu)點(diǎn)
- 減少數(shù)據(jù)庫訪問:緩存命中時(shí)無需執(zhí)行 SQL,降低數(shù)據(jù)庫壓力,尤其適合高頻查詢、低頻修改的數(shù)據(jù)(如商品分類、字典表)。
- 提升查詢性能:緩存查詢?yōu)閮?nèi)存操作,響應(yīng)速度遠(yuǎn)快于數(shù)據(jù)庫 IO,可顯著減少接口響應(yīng)時(shí)間。
- 一級(jí)緩存自動(dòng)維護(hù):無需手動(dòng)配置,默認(rèn)生效,適合單會(huì)話內(nèi)的重復(fù)查詢(如一次請(qǐng)求中多次查詢同一用戶信息)。
- 二級(jí)緩存靈活性高:支持自定義緩存實(shí)現(xiàn)(如集成 Redis 實(shí)現(xiàn)分布式緩存),可根據(jù)業(yè)務(wù)需求配置回收策略、過期時(shí)間等。
- 與事務(wù)兼容:增刪改操作會(huì)自動(dòng)清空相關(guān)緩存,減少臟數(shù)據(jù)風(fēng)險(xiǎn)(需正確使用)。
三、MyBatis 緩存的缺點(diǎn)
- 一級(jí)緩存局限性:
- 僅在 SqlSession 內(nèi)有效,多會(huì)話共享數(shù)據(jù)需依賴二級(jí)緩存。
- 若 SqlSession 未關(guān)閉,長時(shí)間持有緩存可能導(dǎo)致數(shù)據(jù)過期(如其他會(huì)話修改了數(shù)據(jù),當(dāng)前會(huì)話仍使用舊緩存)。
- 二級(jí)緩存潛在問題:
- 臟數(shù)據(jù)風(fēng)險(xiǎn):多表關(guān)聯(lián)查詢時(shí),若關(guān)聯(lián)表的數(shù)據(jù)在其他 Mapper 中修改,當(dāng)前 Mapper 的二級(jí)緩存可能未同步更新,導(dǎo)致查詢到臟數(shù)據(jù)。
例如:OrderMapper緩存了包含用戶信息的訂單數(shù)據(jù),若UserMapper修改了用戶信息,OrderMapper的緩存仍為舊數(shù)據(jù)。 - 分布式環(huán)境不兼容:默認(rèn)二級(jí)緩存為本地內(nèi)存緩存,分布式系統(tǒng)中多節(jié)點(diǎn)緩存無法同步,可能導(dǎo)致數(shù)據(jù)不一致(需集成 Redis 等分布式緩存解決)。
- 緩存鍵設(shè)計(jì)復(fù)雜:
CacheKey依賴 SQL、參數(shù)、分頁等信息,若查詢條件細(xì)微差異(如參數(shù)順序不同),會(huì)導(dǎo)致緩存不命中,浪費(fèi)緩存空間。
- 緩存維護(hù)成本:
- 需手動(dòng)配置二級(jí)緩存,且需根據(jù)業(yè)務(wù)調(diào)整回收策略、過期時(shí)間等參數(shù),增加開發(fā)成本。
- 對(duì)于高頻修改的數(shù)據(jù)(如庫存、訂單狀態(tài)),緩存命中率低,反而可能因緩存更新帶來額外開銷。
- 調(diào)試難度增加:緩存的存在可能掩蓋 SQL 性能問題(如慢查詢因緩存命中未暴露),且排查緩存相關(guān)的臟數(shù)據(jù)問題較為復(fù)雜。
四、適用場景與最佳實(shí)踐
- 適合使用緩存:
- 高頻查詢、低頻修改的數(shù)據(jù)(如商品類目、地區(qū)信息、字典表)。
- 單表查詢或關(guān)聯(lián)關(guān)系簡單的查詢(避免多表關(guān)聯(lián)導(dǎo)致的緩存不一致)。
- 分布式環(huán)境下,建議使用 Redis 等分布式緩存替代默認(rèn)二級(jí)緩存。
- 不適合使用緩存:
- 高頻修改的數(shù)據(jù)(如庫存、實(shí)時(shí)銷量)。
- 多表關(guān)聯(lián)復(fù)雜的查詢(難以保證緩存一致性)。
- 數(shù)據(jù)實(shí)時(shí)性要求極高的場景(如金融交易數(shù)據(jù))。
- 最佳實(shí)踐:
- 優(yōu)先利用一級(jí)緩存,避免在 SqlSession 中執(zhí)行無關(guān)操作,減少緩存無效清空。
- 二級(jí)緩存按需開啟,對(duì)核心 Mapper 單獨(dú)配置,避免全局開啟導(dǎo)致的緩存膨脹。
- 多表關(guān)聯(lián)查詢時(shí),可通過
@CacheNamespaceRef關(guān)聯(lián)相關(guān) Mapper,確保緩存同步清空。 - 分布式系統(tǒng)中,集成 Redis 作為二級(jí)緩存,保證緩存一致性。
總結(jié)
MyBatis 緩存機(jī)制通過一級(jí)緩存和二級(jí)緩存的配合,有效提升了查詢性能,但也存在緩存一致性、分布式兼容等問題。實(shí)際使用中需根據(jù)業(yè)務(wù)場景合理配置,權(quán)衡性能與數(shù)據(jù)準(zhǔn)確性,避免濫用緩存導(dǎo)致的隱性問題。
到此這篇關(guān)于深入解析Mybatis中緩存機(jī)制及優(yōu)缺點(diǎn)的文章就介紹到這了,更多相關(guān)Mybatis緩存機(jī)制內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java操作Word文檔的全攻略(讀取doc與docx文件)
在當(dāng)今辦公自動(dòng)化和文檔處理場景中,Java開發(fā)者經(jīng)常需要處理Word文檔(.doc和.docx格式),無論是數(shù)據(jù)提取、文檔轉(zhuǎn)換還是內(nèi)容分析,掌握高效的Word文檔操作技術(shù)至關(guān)重要,本文將全面介紹Java中讀取兩種主流Word格式的技術(shù)方案、核心API和最佳實(shí)踐,需要的朋友可以參考下2025-07-07
Java編程實(shí)現(xiàn)提取文章中關(guān)鍵字的方法
這篇文章主要介紹了Java編程實(shí)現(xiàn)提取文章中關(guān)鍵字的方法,較為詳細(xì)的分析了Java提取文章關(guān)鍵字的原理與具體實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11
Java中StringBuffer和StringBuilder_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
StringBuffer、StringBuilder和String一樣,也用來代表字符串。String類是不可變類,StringBuffer則是可變類,任何對(duì)它所指代的字符串的改變都不會(huì)產(chǎn)生新的對(duì)象。本文重點(diǎn)給大家介紹String、StringBuffer、StringBuilder區(qū)別,感興趣的朋友一起看看吧2017-04-04
SpringBoot+Mybatis實(shí)現(xiàn)Mapper接口與Sql綁定幾種姿勢
通常我們?cè)谑褂肕ybatis進(jìn)行開發(fā)時(shí),會(huì)選擇xml文件來寫對(duì)應(yīng)的sql,然后將Mapper接口與sql的xml文件建立綁定關(guān)系,然后在項(xiàng)目中調(diào)用mapper接口就可以執(zhí)行對(duì)應(yīng)的sql,感興趣的可以學(xué)習(xí)一下2021-09-09
SpringBoot中的@Configuration注解詳解
這篇文章主要介紹了SpringBoot中的@Configuration注解詳解,Spring Boot推薦使用JAVA配置來完全代替XML 配置,JAVA配置就是通過 @Configuration和 @Bean兩個(gè)注解實(shí)現(xiàn)的,需要的朋友可以參考下2023-08-08
java利用pdfbox+poi往pdf插入數(shù)據(jù)
這篇文章主要給大家介紹了關(guān)于java利用pdfbox+poi如何往pdf插入數(shù)據(jù)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-02-02
java設(shè)計(jì)模式之工廠模式實(shí)例詳解
這篇文章主要介紹了java設(shè)計(jì)模式之工廠模式,結(jié)合具有實(shí)例形式分析了java工廠模式的概念、原理、實(shí)現(xiàn)與使用方法,需要的朋友可以參考下2017-09-09
java實(shí)現(xiàn)科研信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java科研信息管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02

