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

MyBatis 關(guān)聯(lián)查詢延遲加載實戰(zhàn)案例

 更新時間:2026年05月08日 15:21:35   作者:Java成神之路-  
本文介紹了MyBatis開發(fā)中一對多、一對一關(guān)聯(lián)查詢的配置方法,重點講解了resultMap、association、collection等核心標簽的使用場景和用語法,并詳細解釋了延遲加載(fetchType屬性)的配置方法和執(zhí)行流程,最后總結(jié)了單表查詢、一對一關(guān)聯(lián)和一對多關(guān)聯(lián)的配置方法和注意事項

前言

在MyBatis開發(fā)中,單表查詢我們直接用resultType就能輕松搞定,但遇到一對多、一對一關(guān)聯(lián)查詢(如1個用戶對應(yīng)多個訂單、1個訂單對應(yīng)1個用戶),且需要優(yōu)化性能時,就必須用到resultMap配合延遲加載

一、核心基礎(chǔ)概念

1. 業(yè)務(wù)場景:一對多關(guān)系

最經(jīng)典的場景:用戶表(一) ↔ 訂單表(多)

  • 1個用戶可以擁有多個訂單
  • 1個訂單只屬于1個用戶

對應(yīng)Java實體類設(shè)計:

// 用戶實體(一的一方)
@Data
public class User {
    private Integer id;
    private String username;
    // 一對多:存放當前用戶的所有訂單
    private List<Order> orderList;
}
// 訂單實體(多的一方)
@Data
public class Order {
    private Integer id;
    private String orderNo;
    // 多對一:存放訂單所屬的用戶
    private User user;
}

2. 立即加載 VS 延遲加載(懶加載)

這是性能優(yōu)化的核心,也是配置fetchType="lazy"的意義:

加載方式含義優(yōu)缺點
立即加載查詢數(shù)據(jù)時,同時查詢關(guān)聯(lián)數(shù)據(jù)代碼簡單;查詢?nèi)哂?,性能?/td>
延遲加載查詢時只查本身數(shù)據(jù),用到關(guān)聯(lián)數(shù)據(jù)時才查詢減少冗余SQL,性能高;需要額外配置
通俗理解:延遲加載就是按需加載,用不到的數(shù)據(jù)絕不查詢!

二、為什么要寫 resultMap?(關(guān)聯(lián)查詢專用)

1. 單表查詢

日常單查用戶/訂單,一行代碼搞定,完全不用復(fù)雜配置:

<!-- 單表查詢:resultType 直接映射,無需配置resultMap -->
<select id="selectById" resultType="com.itheima.pojo.User">
    select * from tb_user where id = #{id}
</select>

? 適用場景:純單表查詢,無關(guān)聯(lián)關(guān)系

2. 必須用復(fù)雜配置的場景

當需求變?yōu)椋?strong>查詢主數(shù)據(jù) + 按需加載關(guān)聯(lián)數(shù)據(jù)

MyBatis規(guī)定:一對多/一對一關(guān)聯(lián) + 延遲加載,必須使用 resultMap 配置

這是固定語法!

三、一對一延遲加載(association 標簽)

一對一場景:訂單表 ↔ 用戶表(1個訂單只屬于1個用戶),MyBatis用association標簽實現(xiàn)一對一延遲加載!

1. 一對一核心配置

<?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.itheima.mapper.OrderMapper">
    <!-- 一對一結(jié)果映射 -->
    <resultMap id="orderResultMap" type="order" autoMapping="true">
        <id property="id" column="id"/>
        <result property="orderNo" column="order_no"/>
        <!-- 一對一關(guān)聯(lián)配置:延遲加載用戶信息 -->
        <association
            property="user"
            javaType="user"
            select="com.itheima.mapper.UserMapper.selectById"
            column="user_id"
            fetchType="lazy">
        </association>
    </resultMap>
    <!-- 根據(jù)id查詢訂單 -->
    <select id="selectById" resultMap="orderResultMap">
        select * from tb_order where id = #{id}
    </select>
</mapper>

? association 標簽5大核心屬性

  1. property:實體類中關(guān)聯(lián)對象屬性名(Order類中的user)
  2. javaType:關(guān)聯(lián)對象的實體類型
  3. select:延遲加載調(diào)用的查詢方法全路徑
  4. column:傳遞給子查詢的參數(shù)(訂單表的user_id)
  5. fetchType="lazy":開啟一對一延遲加載

四、一對多延遲加載(collection 標簽)

<?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.itheima.mapper.UserMapper">
    <!-- 1. 定義復(fù)雜映射規(guī)則:id唯一標識,type映射實體類,autoMapping自動匹配字段 -->
    <resultMap id="userResultMap" type="user" autoMapping="true">
        <!-- 2. 主鍵映射(規(guī)范寫法,可省略) -->
        <id property="id" column="id"/>
        <!-- 普通字段映射(autoMapping=true可自動匹配,可省略) -->
        <result property="username" column="username"/>
        <!-- 3. 核心:一對多關(guān)聯(lián)映射,延遲加載配置 -->
        <collection
            property="orderList"
            ofType="order"
            select="com.itheima.mapper.OrderMapper.findByUid"
            column="id"
            fetchType="lazy">
        </collection>
    </resultMap>
    <!-- 4. 查詢用戶,綁定上面的映射規(guī)則 -->
    <select id="selectById" resultMap="userResultMap">
        select * from tb_user where id = #{id}
    </select>
</mapper>

? collection 標簽5大核心屬性

這是一對多配置的靈魂,記住這5個屬性,再也不會寫錯:

  1. property:實體類中集合屬性的名稱(必須和User類中的orderList一致)
  2. ofType:集合中存儲的實體類型
  3. select:延遲加載時執(zhí)行的子查詢方法全路徑
  4. column:傳遞給子查詢的參數(shù)列(用戶id)
  5. fetchType="lazy"開啟延遲加載(默認是立即加載)

五、完整實戰(zhàn)代碼

1. MyBatis全局配置(開啟延遲加載總開關(guān))

<settings>
    <!-- 開啟延遲加載總開關(guān) -->
    <setting name="lazyLoadingEnabled" value="true"/>
    <!-- 關(guān)閉積極加載(3.4.1后默認false,配置更保險) -->
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>

lazyLoadingEnabled(總開關(guān))

作用:控制 是否開啟延遲加載

默認值:false → 關(guān)閉延遲加載,默認使用立即加載

人話:查詢主數(shù)據(jù)時,直接把關(guān)聯(lián)數(shù)據(jù)一起查出來,不等待調(diào)用

aggressiveLazyLoading(觸發(fā)方式)

作用:控制 延遲加載的觸發(fā)條件

默認值:false

人話:只有開啟了延遲加載(lazyLoadingEnabled=true),這個配置才有用!

true:調(diào)用對象任何方法(toString/equals/getter)都觸發(fā)加載

false:只調(diào)用關(guān)聯(lián)屬性的 getter 方法才觸發(fā)加載(最標準的懶加載)

2. 子查詢Mapper配置

一對多/一對一依賴的子查詢方法必須單獨定義:

<mapper namespace="com.itheima.mapper.OrderMapper">
    <!-- 根據(jù)用戶id查詢訂單:供一對多延遲加載調(diào)用 -->
    <select id="findByUid" resultType="com.itheima.pojo.Order">
        select * from tb_order where user_id = #{userId}
    </select>
</mapper>

3. Mapper接口

// UserMapper
public interface UserMapper {
    User selectById(Integer id);
}
// OrderMapper
public interface OrderMapper {
    List<Order> findByUid(Integer userId);
    Order selectById(Integer id);
}

六、延遲加載執(zhí)行流程

1. 一對一執(zhí)行流程

@Test
public void testOneToOne(){
    // 1. 僅查詢訂單:只執(zhí)行1條SQL → select * from tb_order where id=1
    Order order = orderMapper.selectById(1);
    System.out.println("訂單編號:" + order.getOrderNo());
    // 2. 調(diào)用user:觸發(fā)一對一延遲加載,查詢用戶信息
    System.out.println("訂單所屬用戶:" + order.getUser());
}

2. 一對多執(zhí)行流程

@Test
public void testLazyLoad(){
    // 1. 僅查詢用戶:只執(zhí)行1條SQL → select * from tb_user where id=1
    User user = userMapper.selectById(1);
    System.out.println("查詢到用戶:" + user.getUsername());
    // 2. 未使用訂單數(shù)據(jù):不執(zhí)行訂單查詢SQL
    // 3. 調(diào)用orderList:觸發(fā)延遲加載,執(zhí)行訂單SQL → select * from tb_order where user_id=1
    System.out.println("用戶訂單:" + user.getOrderList());
}

完美實現(xiàn)按需加載!

七、注意事項

  1. 忘記開啟全局延遲加載
    全局開關(guān) lazyLoadingEnabled(默認 false)控制所有未顯式設(shè)置 fetchType 的關(guān)聯(lián); 局部屬性 fetchType="lazy" 可以獨立讓單個關(guān)聯(lián)延遲加載,不受全局開關(guān)影響。
  2. 子查詢方法不存在/路徑寫錯
    select屬性必須是全限定名,因為這是兩個mapper.xml文件。
  3. 實體類屬性名不匹配
    配置的property屬性必須和實體類屬性名完全一致。
  4. 標簽區(qū)分
    一對多用collection,一對一用association,不可混用!

八、延遲加載的優(yōu)勢

  • 提升性能:避免查詢不需要的關(guān)聯(lián)數(shù)據(jù),減少數(shù)據(jù)庫壓力
  • 解決N+1問題:查詢數(shù)據(jù)時,不會自動查詢關(guān)聯(lián)數(shù)據(jù)
  • 靈活適配業(yè)務(wù):只查主數(shù)據(jù)時,無冗余SQL
  • 通用適配:同時支持一對多、一對一關(guān)聯(lián)場景

九、總結(jié)

  1. 單表查詢:用resultType,無需任何復(fù)雜配置(日常開發(fā)主流);
  2. 一對一關(guān)聯(lián):必須用resultMap + association;
  3. 一對多關(guān)聯(lián):必須用resultMap + collection;
  4. 延遲加載核心fetchType="lazy" + 全局配置開關(guān) + 按需加載;
  5. 核心標簽:association(一對一)、collection(一對多),語法結(jié)構(gòu)高度一致,僅標簽和類型屬性不同。

到此這篇關(guān)于MyBatis 關(guān)聯(lián)查詢延遲加載案例的文章就介紹到這了,更多相關(guān)mybatis 延遲加載內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MyBatis分頁的四種方式

    MyBatis分頁的四種方式

    分頁查詢是非常常見的需求,本文主要介紹了MyBatis分頁的四種方式,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • Spring核心容器之ApplicationContext上下文啟動準備詳解

    Spring核心容器之ApplicationContext上下文啟動準備詳解

    這篇文章主要介紹了Spring核心容器之ApplicationContext上下文啟動準備詳解,ApplicationContext 繼承自 BeanFactory ,其不僅包含 BeanFactory 所有功能,還擴展了容器功能,需要的朋友可以參考下
    2023-11-11
  • java實現(xiàn)可逆加密算法

    java實現(xiàn)可逆加密算法

    這篇文章主要為大家詳細介紹了java實現(xiàn)可逆加密算法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-03-03
  • Spring Cloud體系實現(xiàn)標簽路由的方法示例

    Spring Cloud體系實現(xiàn)標簽路由的方法示例

    這篇文章主要介紹了Spring Cloud體系實現(xiàn)標簽路由的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • MyBatis中的循環(huán)插入insert foreach問題

    MyBatis中的循環(huán)插入insert foreach問題

    這篇文章主要介紹了MyBatis中的循環(huán)插入insert foreach問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • Java并發(fā)編程之Lock鎖機制從使用到源碼實現(xiàn)

    Java并發(fā)編程之Lock鎖機制從使用到源碼實現(xiàn)

    這篇文章主要介紹了Java并發(fā)編程之Lock鎖機制從使用到源碼實現(xiàn),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2025-10-10
  • Java中ArrayList、Vector、LinkedList的核心區(qū)別與應(yīng)用場景詳解

    Java中ArrayList、Vector、LinkedList的核心區(qū)別與應(yīng)用場景詳解

    在Java編程語言中ArrayList、Vector和LinkedList是三個常見的列表實現(xiàn),它們都實現(xiàn)了List接口,這篇文章主要介紹了Java中ArrayList、Vector、LinkedList的核心區(qū)別與應(yīng)用場景的相關(guān)資料,需要的朋友可以參考下
    2025-07-07
  • Java基礎(chǔ)語法:邏輯控制

    Java基礎(chǔ)語法:邏輯控制

    下面小編就為大家?guī)硪黄狫ava邏輯控制的基礎(chǔ)文章。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2021-08-08
  • Java虛擬機裝載和初始化一個class類代碼解析

    Java虛擬機裝載和初始化一個class類代碼解析

    這篇文章的主要內(nèi)容是Java虛擬機裝載和初始化一個class類的代碼解析,包括介紹了裝載和初始化的時機與方式,需要的朋友可以參考下。
    2017-09-09
  • spring?boot前后端交互之數(shù)據(jù)格式轉(zhuǎn)換問題

    spring?boot前后端交互之數(shù)據(jù)格式轉(zhuǎn)換問題

    這篇文章主要介紹了spring?boot前后端交互之數(shù)據(jù)格式轉(zhuǎn)換,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-01-01

最新評論

广德县| 怀化市| 宜都市| 双柏县| 双流县| 从化市| 聂荣县| 凤阳县| 独山县| 威宁| 肇源县| 轮台县| 交城县| 苏州市| 余姚市| 平江县| 依安县| 保德县| 永州市| 静海县| 嘉定区| 石景山区| 衡阳市| 崇文区| 鄂州市| 湛江市| 错那县| 瓦房店市| 武胜县| 刚察县| 弥勒县| 安龙县| 云南省| 黄石市| 叶城县| 平泉县| 新巴尔虎右旗| 河池市| 昆明市| 维西| 资中县|