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

MyBatis 延遲加載與緩存的實現(xiàn)

 更新時間:2025年05月19日 08:58:36   作者:lyrhhhhhhhh  
本文主要介紹了MyBatis 延遲加載與緩存的實現(xiàn)

一、延遲加載策略:按需加載,優(yōu)化性能

1. 延遲加載 vs 立即加載:核心區(qū)別

  • 立即加載:主查詢(如查詢用戶)執(zhí)行時,主動關(guān)聯(lián)加載關(guān)聯(lián)數(shù)據(jù)(如用戶的所有賬號)。
    • 場景:多對一查詢(如賬號關(guān)聯(lián)用戶),需立即獲取關(guān)聯(lián)數(shù)據(jù)。
  • 延遲加載:主查詢執(zhí)行時暫不加載關(guān)聯(lián)數(shù)據(jù),僅當(dāng)程序訪問關(guān)聯(lián)數(shù)據(jù)時,再觸發(fā)子查詢。
    • 場景:一對多查詢(如用戶關(guān)聯(lián)多個賬號),減少初始查詢壓力。

舉個小例子: 

場景:查詢用戶信息時不立即加載其訂單,僅在需要查看訂單時再觸發(fā)查詢。
示例:電商用戶詳情頁先展示用戶姓名、地址,點擊 “查看訂單” 按鈕時,才加載該用戶的訂單列表。 

 2. 多對一延遲加載實現(xiàn)(Account → User)

步驟解析:

1、定義關(guān)聯(lián)查詢:主查詢僅查賬號表,關(guān)聯(lián)用戶信息通過子查詢延遲加載。

<!-- 主查詢:僅查賬號 -->
<select id="findAll" resultMap="accountMap">
  SELECT * FROM account
</select>

<!-- 子查詢:通過用戶ID查用戶信息 -->
<select id="findById" parameterType="int" resultType="User">
  SELECT * FROM user WHERE id = #{id}
</select>

2、配置延遲加載:通過 association 標簽指定子查詢路徑和參數(shù)。

<resultMap type="Account" id="accountMap">
  <association 
    property="user"          <!-- Account類中的User屬性 -->
    javaType="User"          <!-- 關(guān)聯(lián)對象類型 -->
    select="findById"        <!-- 子查詢方法名 -->
    column="uid"             <!-- 主查詢結(jié)果中用于關(guān)聯(lián)的列(賬號表的uid) -->
  />
</resultMap>

3、全局開啟延遲加載:在 SqlMapConfig.xml 中配置。

<settings>
  <setting name="lazyLoadingEnabled" value="true"/>   <!-- 開啟延遲加載 -->
  <setting name="aggressiveLazyLoading" value="false"/> <!-- 關(guān)閉積極加載(默認會加載所有關(guān)聯(lián)數(shù)據(jù)) -->
</settings>

 測試驗證:

@Test
public void testLazyLoading() {
  List<Account> accounts = accountMapper.findAll();
  for (Account account : accounts) {
    System.out.println("賬號金額:" + account.getMoney()); // 主查詢執(zhí)行時僅輸出金額
    System.out.println("用戶名稱:" + account.getUser().getUsername()); // 首次訪問user時觸發(fā)子查詢
  }
}

 3. 一對多延遲加載實現(xiàn)(User → Accounts)

 核心配置:

<!-- 主查詢:僅查用戶表 -->
<select id="findAll" resultMap="userMap">
  SELECT * FROM user
</select>

<resultMap type="User" id="userMap">
  <collection 
    property="accounts"       <!-- User類中的賬號列表屬性 -->
    ofType="Account"          <!-- 集合元素類型 -->
    select="com.qcbyjy.mapper.AccountMapper.findByUid" <!-- 子查詢:通過用戶ID查賬號 -->
    column="id"                <!-- 主查詢結(jié)果中的用戶ID -->
  />
</resultMap>

<!-- 子查詢:根據(jù)用戶ID查賬號 -->
<select id="findByUid" parameterType="int" resultType="Account">
  SELECT * FROM account WHERE uid = #{uid}
</select>

關(guān)鍵區(qū)別:

  • 多對一用 association(單個對象),一對多用 collection(集合)。
  • 子查詢參數(shù)通過 column 傳遞主查詢結(jié)果中的字段(如用戶表的 id)。

 二、MyBatis 緩存機制:減少數(shù)據(jù)庫訪問

 1. 緩存的核心價值

  • 定義:將頻繁查詢的數(shù)據(jù)臨時存儲在內(nèi)存中,避免重復(fù)訪問數(shù)據(jù)庫,提升查詢速度。
  • 適用場景:讀多寫少、數(shù)據(jù)更新不頻繁的數(shù)據(jù)(如字典表、配置信息)。

 2. 一級緩存:SqlSession 級別的緩存

(1)本質(zhì)與作用

  • 作用域:基于 SqlSession 對象,同一 SqlSession 內(nèi)的相同查詢會直接從緩存獲取結(jié)果。
  • 實現(xiàn)原理SqlSession 內(nèi)部維護一個 HashMap,鍵為查詢的唯一標識(SQL + 參數(shù)),值為查詢結(jié)果對象。

(2)驗證一級緩存

@Test
public void testFirstLevelCache() {
  // 同一 SqlSession 內(nèi)的兩次相同查詢
  User user1 = userMapper.findById(1);
  User user2 = userMapper.findById(1); // 直接從緩存獲取,不執(zhí)行 SQL
  System.out.println(user1 == user2); // 輸出 true(對象引用相同)
}

(3)緩存失效場景

  • SqlSession 關(guān)閉或提交(commit)。
  • 執(zhí)行 update/insert/delete 操作(會清空緩存)。
  • 手動調(diào)用 session.clearCache() 清空緩存。

 3. 二級緩存:SqlSessionFactory 級別的緩存

(1)核心概念

  • 作用域:基于 SqlSessionFactory,跨 SqlSession 共享緩存(如多個 SqlSession 執(zhí)行相同查詢)。
  • 實現(xiàn)條件

    實體類需實現(xiàn) Serializable 接口(支持序列化存儲)。

    在 SqlMapConfig.xml 中開啟二級緩存(默認已開啟)。

    在 Mapper 中配置 <cache/> 標簽。

(2)配置步驟

1、 實體類實現(xiàn)序列化

public class User implements Serializable {
  // 省略屬性和方法
}

2、Mapper 中啟用緩存

<mapper namespace="com.qcbyjy.mapper.UserMapper">
  <cache/> <!-- 啟用二級緩存 -->
  
  <select id="findById" resultType="User" useCache="true">
    SELECT * FROM user WHERE id = #{id}
  </select>
</mapper>

3、配置緩存策略(可選)

<cache 
  eviction="LRU"       <!-- 緩存淘汰策略:LRU(最近最少使用) -->
  flushInterval="60000" <!-- 自動刷新間隔(毫秒) -->
  size="512"           <!-- 最大緩存對象數(shù) -->
  readOnly="true"      <!-- 是否只讀:true(共享對象)/ false(復(fù)制對象) -->
/>

(3)緩存優(yōu)先級與刷新

  • 優(yōu)先級:二級緩存 > 一級緩存 > 數(shù)據(jù)庫查詢。
  • 刷新機制:執(zhí)行 update/insert/delete 時,會清空對應(yīng) Mapper 的二級緩存。

(4)測試驗證

@Test
public void testSecondLevelCache() {
  try (SqlSession session1 = factory.openSession()) {
    UserMapper mapper1 = session1.getMapper(UserMapper.class);
    User user1 = mapper1.findById(1); // 首次查詢,命中數(shù)據(jù)庫
  }

  try (SqlSession session2 = factory.openSession()) {
    UserMapper mapper2 = session2.getMapper(UserMapper.class);
    User user2 = mapper2.findById(1); // 第二次查詢,命中二級緩存,不執(zhí)行 SQL
  }
}

 三、總結(jié):性能優(yōu)化核心要點

技術(shù)核心作用關(guān)鍵配置
延遲加載減少初始查詢數(shù)據(jù)量,提升響應(yīng)速度lazyLoadingEnabledassociation/collection 的 select 屬性
一級緩存減少同一會話內(nèi)的重復(fù)查詢自動生效,無需額外配置(注意 SqlSession 生命周期)
二級緩存跨會話共享緩存,減少數(shù)據(jù)庫壓力實體類序列化、<cache/> 標簽、緩存策略配置

合理運用延遲加載和緩存,能顯著提升 MyBatis 應(yīng)用的性能,但需根據(jù)業(yè)務(wù)場景靈活選擇,避免過度使用導(dǎo)致數(shù)據(jù)不一致或內(nèi)存溢出。

到此這篇關(guān)于MyBatis 延遲加載與緩存的實現(xiàn)的文章就介紹到這了,更多相關(guān)MyBatis 延遲加載與緩存內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java微信企業(yè)號開發(fā)之發(fā)送消息(文本、圖片、語音)

    java微信企業(yè)號開發(fā)之發(fā)送消息(文本、圖片、語音)

    這篇文章主要為大家詳細介紹了java微信企業(yè)號開發(fā)之發(fā)送消息,發(fā)送類型包括文本、圖片、語音,感興趣的小伙伴們可以參考一下
    2016-06-06
  • 詳解IDEA中MAVEN項目打JAR包的簡單方法

    詳解IDEA中MAVEN項目打JAR包的簡單方法

    本篇文章主要介紹了詳解IDEA中MAVEN項目打JAR包的簡單方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-12-12
  • java逐行讀取文件(讀取文件每一行、按行讀取文件)附帶詳細代碼

    java逐行讀取文件(讀取文件每一行、按行讀取文件)附帶詳細代碼

    這篇文章主要給大家介紹了關(guān)于java逐行讀取文件(讀取文件每一行、按行讀取文件)的相關(guān)資料,讀取文件是我們在日常工作中經(jīng)常遇到的一個需求,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2023-09-09
  • Java創(chuàng)建線程的方式解析

    Java創(chuàng)建線程的方式解析

    這篇文章主要介紹了Java創(chuàng)建線程的方式解析,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下,希望對你的學(xué)習(xí)有所幫助
    2022-07-07
  • Java高效實現(xiàn)復(fù)制PPT(PowerPoint)幻燈片

    Java高效實現(xiàn)復(fù)制PPT(PowerPoint)幻燈片

    在日常的開發(fā)工作中,我們經(jīng)常會遇到需要對Office文檔進行編程處理的需求,本文將為您揭示如何利用強大的 Spire.Presentation for Java進行PPT復(fù)制,有需要的小伙伴可以了解下
    2025-09-09
  • Springboot?-?Fat?Jar示例詳解

    Springboot?-?Fat?Jar示例詳解

    這篇文章主要介紹了Springboot?-?Fat?Jar詳解,Spring?Boot內(nèi)嵌容器,通過java?-jar命令便可以直接啟動應(yīng)用,今天帶著大家探索FAT?JAR啟動的背后原理,需要的朋友可以參考下
    2023-02-02
  • Spring的Xml和JavaConfig 擴展哪個好用

    Spring的Xml和JavaConfig 擴展哪個好用

    今天給大家介紹基于注解的Spring擴展,Spring的Xml和JavaConfig 擴展的配置方法,關(guān)于Spring的Xml和JavaConfig 擴展你會選哪個呢,帶著這個問題一起通過本文學(xué)習(xí)下吧
    2021-05-05
  • 基于Java回顧之I/O的使用詳解

    基于Java回顧之I/O的使用詳解

    我計劃在接下來的幾篇文章中快速回顧一下Java,主要是一些基礎(chǔ)的JDK相關(guān)的內(nèi)容
    2013-05-05
  • nacos配置讀取實現(xiàn)過程

    nacos配置讀取實現(xiàn)過程

    本文介紹了在Spring Boot應(yīng)用中如何指定和使用配置文件,創(chuàng)建配置類讀取Nacos配置,并通過接口返回給前端,同時使用@RefreshScope實現(xiàn)配置實時刷新
    2026-01-01
  • java初學(xué)者如何讓編程學(xué)習(xí)起來更簡單

    java初學(xué)者如何讓編程學(xué)習(xí)起來更簡單

    我們給大家?guī)硪黄P(guān)于java初學(xué)者如何讓編程學(xué)習(xí)起來更簡單的基礎(chǔ)性文章,有需要的朋友們可以學(xué)習(xí)下。
    2020-11-11

最新評論

班戈县| 廊坊市| 黑龙江省| 巴塘县| 新乐市| 马龙县| 广灵县| 莲花县| 惠东县| 凤翔县| 略阳县| 怀仁县| 寻甸| 安达市| 繁昌县| 水城县| 广南县| 扎兰屯市| 区。| 屏东县| 紫阳县| 抚顺市| 铜山县| 馆陶县| 定日县| 南宁市| 富宁县| 荃湾区| 廉江市| 沽源县| 兴业县| 克什克腾旗| 察雅县| 苗栗县| 义马市| 棋牌| 泸定县| 德令哈市| 汤阴县| 林芝县| 蒙城县|