最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mybatis中的緩存機制解析

 更新時間:2025年11月12日 10:08:36   作者:程序員小假  
這篇文章給大家介紹mybatis中的緩存機制,本文結(jié)合實例代碼給大家介紹的非常詳細,感興趣的朋友跟隨小編一起看看吧

核心概覽

  • 一級緩存:默認開啟,作用范圍在 同一個 SqlSession 內(nèi)。
  • 二級緩存:需要手動配置開啟,作用范圍在 同一個 Mapper 命名空間(即同一個 Mapper 接口)內(nèi),可以被多個 SqlSession 共享。

一級緩存

1. 作用域

  • SqlSession 級別:當(dāng)同一個 SqlSession 執(zhí)行相同的 SQL 查詢時,MyBatis 會優(yōu)先從緩存中獲取數(shù)據(jù),而不是直接查詢數(shù)據(jù)庫。
  • 它是 默認開啟 的,無法關(guān)閉,但可以配置其作用范圍(SESSIONSTATEMENT)。

2. 工作機制

  1. 第一次執(zhí)行查詢后,查詢結(jié)果會被存儲到 SqlSession 關(guān)聯(lián)的一級緩存中。
  2. 在同一個 SqlSession 中,再次執(zhí)行 完全相同的 SQL 查詢(包括語句和參數(shù))時,會直接返回緩存中的對象,而不會去數(shù)據(jù)庫查詢。
  3. 如果 SqlSession 執(zhí)行了 增(INSERT)、刪(DELETE)、改(UPDATE) 操作,或者調(diào)用了 commit()close()、rollback() 方法,該 SqlSession 的一級緩存會被清空。這是為了防止讀取到臟數(shù)據(jù)。

3. 示例說明

// 假設(shè)獲取的 SqlSession 和 UserMapper
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    // 第一次查詢,會發(fā)送 SQL 到數(shù)據(jù)庫
    User user1 = mapper.selectUserById(1L);
    System.out.println(user1);
    // 第二次查詢,SQL 和參數(shù)完全相同,直接從一級緩存返回,不查詢數(shù)據(jù)庫
    User user2 = mapper.selectUserById(1L);
    System.out.println(user2);
    // 判斷是否為同一個對象(是,因為從緩存中返回的是同一個對象的引用)
    System.out.println(user1 == user2); // 輸出:true
    // 執(zhí)行一個更新操作
    mapper.updateUser(user1);
    // 此時,一級緩存被清空
    // 第三次查詢,因為緩存被清空,會再次發(fā)送 SQL 到數(shù)據(jù)庫
    User user3 = mapper.selectUserById(1L);
    System.out.println(user3 == user1); // 輸出:false (雖然是同一條數(shù)據(jù),但已是新對象)
}

4. 注意事項

  • 對象相同:一級緩存返回的是 同一個對象的引用,因此在同一個 SqlSession 內(nèi),你操作的都是同一個 Java 對象。
  • 分布式環(huán)境:一級緩存無法在多個應(yīng)用服務(wù)器之間共享,因為它綁定在單個請求的 SqlSession 上。

二級緩存

1. 作用域

  • Mapper 級別 / Namespace 級別:多個 SqlSession 在訪問同一個 Mapper 的查詢時,可以共享其緩存。
  • 它是 默認關(guān)閉 的,需要在全局配置中開啟,并在具體的 Mapper XML 中顯式配置。

2. 開啟與配置

a. 全局配置文件 (mybatis-config.xml):
必須顯式設(shè)置開啟二級緩存(雖然默認是 true,但顯式聲明是個好習(xí)慣)。

<configuration>
<settings>
<!-- 開啟全局二級緩存,默認就是 true,但建議寫明 -->
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>

b. Mapper XML 文件
在需要開啟二級緩存的 Mapper.xml 中添加 <cache/> 標(biāo)簽。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
<!-- 開啟本 Mapper 的二級緩存 -->
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
<!-- 其他 SQL 定義 -->
<select id="selectUserById" parameterType="long" resultType="User" useCache="true">
SELECT * FROM user WHERE id = #{id}
</select>
</mapper>
  • <cache/> 標(biāo)簽屬性:
  • eviction:緩存回收策略。
  • LRU(默認):最近最少使用。
  • FIFO:先進先出。
  • SOFT:軟引用,基于垃圾回收器狀態(tài)和軟引用規(guī)則移除。
  • WEAK:弱引用,更積極地移除。
  • flushInterval:緩存刷新間隔(毫秒),默認不清空。
  • size:緩存存放多少元素。
  • readOnly:是否為只讀。
  • true:返回相同的緩存對象實例,性能好,但不允許修改。
  • false(默認):通過序列化返回緩存對象的拷貝,安全,性能稍差。

3. 工作機制

  1. 當(dāng)一個 SqlSession 執(zhí)行查詢后,在關(guān)閉或提交時,其查詢結(jié)果會被存入二級緩存。
  2. 另一個 SqlSession 執(zhí)行相同的查詢時,會先從二級緩存中查找數(shù)據(jù)。如果找到,則直接返回,否則再去數(shù)據(jù)庫查詢。
  3. 任何一個 SqlSession 執(zhí)行了 增、刪、改 操作并 commit() 后,會清空 整個對應(yīng) Mapper 的二級緩存,以保證數(shù)據(jù)一致性。

4. 示例說明

// 第一個 SqlSession
try (SqlSession sqlSession1 = sqlSessionFactory.openSession()) {
    UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
    User user1 = mapper1.selectUserById(1L); // 查詢數(shù)據(jù)庫
    sqlSession1.close(); // 關(guān)閉時,數(shù)據(jù)存入二級緩存
}
// 第二個 SqlSession(與第一個不同)
try (SqlSession sqlSession2 = sqlSessionFactory.openSession()) {
    UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
    // 查詢相同的 SQL,直接從二級緩存獲取,不查詢數(shù)據(jù)庫
    User user2 = mapper2.selectUserById(1L);
}
// 第三個 SqlSession,執(zhí)行了更新
try (SqlSession sqlSession3 = sqlSessionFactory.openSession()) {
    UserMapper mapper3 = sqlSession3.getMapper(UserMapper.class);
    User user = mapper3.selectUserById(1L);
    user.setName("New Name");
    mapper3.updateUser(user); // 執(zhí)行更新
    sqlSession3.commit(); // 提交時,清空 UserMapper 的二級緩存
}
// 第四個 SqlSession
try (SqlSession sqlSession4 = sqlSessionFactory.openSession()) {
    UserMapper mapper4 = sqlSession4.getMapper(UserMapper.class);
    // 因為緩存已被清空,所以會再次查詢數(shù)據(jù)庫
    User user4 = mapper4.selectUserById(1L);
}

5. 注意事項

  • 實體類序列化:如果二級緩存的 readOnly="false",那么對應(yīng)的實體類必須實現(xiàn) Serializable 接口。
  • 事務(wù)提交:只有在 SqlSession 執(zhí)行 commit()close() 時,數(shù)據(jù)才會從一級緩存轉(zhuǎn)存到二級緩存。
  • 緩存粒度:二級緩存是 Mapper 級別的,有時會顯得比較粗粒度??梢酝ㄟ^ <cache-ref> 讓多個 Mapper 共享一個緩存,但不推薦,容易引起數(shù)據(jù)混亂。

緩存順序與總結(jié)

當(dāng)發(fā)起一個查詢請求時,MyBatis 的緩存查詢順序是:

  1. 先查二級緩存:查看當(dāng)前 Mapper 的二級緩存中是否有數(shù)據(jù)。
  2. 再查一級緩存:如果二級緩存沒有,再查看當(dāng)前 SqlSession 的一級緩存中是否有數(shù)據(jù)。
  3. 最后查數(shù)據(jù)庫:如果兩級緩存都沒有,才發(fā)送 SQL 語句到數(shù)據(jù)庫執(zhí)行查詢。

查詢到的數(shù)據(jù)會 先存入一級緩存,在 SqlSession 關(guān)閉或提交時,再轉(zhuǎn)存到二級緩存。

特性

一級緩存

二級緩存

作用域

SqlSession

Mapper (Namespace)

默認狀態(tài)

開啟

關(guān)閉

是否共享

否,Session 獨享

是,跨 Session 共享

清空時機

UPDATE/INSERT/DELETE, commit(), close()

同 Mapper 的 UPDATE/INSERT/DELETE + commit()

使用建議

  • 查詢多,修改少的數(shù)據(jù)適合使用二級緩存,如字典表、配置項。
  • 數(shù)據(jù)實時性要求高的場景(如交易、訂單)應(yīng)謹慎使用二級緩存,或者設(shè)置較短的刷新間隔。
  • 在分布式環(huán)境中,默認的二級緩存(基于內(nèi)存)是無法共享的,需要集成 Redis、Ehcache 等第三方緩存中間件來替代。
  • 理解緩存機制有助于解決一些“詭異”的問題,比如在同一個事務(wù)中,先后查詢和更新,但由于一級緩存的存在,后續(xù)查詢可能看不到其他線程的更新。

到此這篇關(guān)于Mybatis 的緩存機制的文章就介紹到這了,更多相關(guān)mybatis 緩存機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java中的connection reset 異常處理分析

    java中的connection reset 異常處理分析

    本文主要介紹了java中的connection reset 異常處理分析的相關(guān)資料,具有很好的參考價值。下面跟著小編一起來看下吧
    2017-04-04
  • Springboot使用Maven占位符@替換不生效問題及解決

    Springboot使用Maven占位符@替換不生效問題及解決

    這篇文章主要介紹了Springboot使用Maven占位符@替換不生效問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • Spring計時器StopWatch的具體使用

    Spring計時器StopWatch的具體使用

    本文主要介紹了Spring計時器StopWatch的具體使用,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • SpringBoot項目啟動執(zhí)行任務(wù)的多種方法小結(jié)

    SpringBoot項目啟動執(zhí)行任務(wù)的多種方法小結(jié)

    這篇文章主要介紹了SpringBoot項目啟動執(zhí)行任務(wù)的多種方法小結(jié),本文給大家分享的這幾種方法經(jīng)常會被用到,當(dāng)我們的項目啟動后需要調(diào)用對應(yīng)的方法,用來項目的初始化等,本文通過示例代碼講解的非常詳細,需要的朋友參考下吧
    2023-07-07
  • Java中的ArrayList和線性表用法及說明

    Java中的ArrayList和線性表用法及說明

    文章介紹了線性表及其常見實現(xiàn)方式,包括順序表和鏈表,重點討論了順序表的實現(xiàn)細節(jié),如接口實現(xiàn)、增刪查改操作、內(nèi)存管理等,同時,文章還簡要介紹了ArrayList的概念及其在Java集合框架中的應(yīng)用,包括ArrayList的構(gòu)造、常見方法和遍歷方式
    2025-12-12
  • druid連接泄露故障全面分析

    druid連接泄露故障全面分析

    這篇文章主要介紹了druid連接泄露故障全面分析,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 解決mapper自動裝配識別不了,Could not autowire.No beans of‘UserMapper‘type found

    解決mapper自動裝配識別不了,Could not autowire.No beans&

    文章介紹了在使用MyBatisX插件和MybatisPlus自動生成代碼后,如何解決Spring Boot項目中自動注入`UserMapper`時報錯的問題,主要方法包括在主配置類或啟動類上添加`@MapperScan`注解,指定Mapper文件夾所在的包路徑,以及在Mapper類上添加`@Repository`注解
    2024-11-11
  • Spring教程之異常捕獲方式

    Spring教程之異常捕獲方式

    這篇文章主要介紹了Spring異常捕獲方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-05-05
  • Maven通過filtering標(biāo)簽讀取變量配置的三種方法

    Maven通過filtering標(biāo)簽讀取變量配置的三種方法

    在日常開發(fā)中,我們大多都會有開發(fā)環(huán)境、測試環(huán)境、生產(chǎn)環(huán)境等,不同環(huán)境的參數(shù)肯定不一樣,本文主要介紹了Maven通過filtering標(biāo)簽讀取變量配置的三種方法,感興趣的可以了解一下
    2024-03-03
  • RocketMq深入分析講解兩種削峰方式

    RocketMq深入分析講解兩種削峰方式

    當(dāng)上游調(diào)用下游服務(wù)速率高于下游服務(wù)接口QPS時,那么如果不對調(diào)用速率進行控制,那么會發(fā)生很多失敗請求,通過消息隊列的削峰方法有兩種,這篇文章主要介紹了RocketMq深入分析講解兩種削峰方式
    2023-01-01

最新評論

北流市| 治县。| 武定县| 临潭县| 博爱县| 垣曲县| 逊克县| 沂源县| 宜州市| 万州区| 彭阳县| 襄樊市| 波密县| 海门市| 土默特左旗| 赞皇县| 灌南县| 巍山| 余姚市| 公主岭市| 江北区| 双牌县| 安新县| 琼中| 棋牌| 辉县市| 北碚区| 政和县| 济源市| 茶陵县| 图们市| 南丰县| 富锦市| 宜良县| 宿迁市| 澜沧| 石门县| 廊坊市| 康马县| 浠水县| 遂昌县|