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

MyBatis中Collection和Association的底層實(shí)現(xiàn)原理分析

 更新時(shí)間:2025年11月28日 08:44:17   作者:shy好好學(xué)習(xí)  
本文詳細(xì)介紹了MyBatis中`<collection>`和`<association>`標(biāo)簽的底層實(shí)現(xiàn)原理,探討了它們?nèi)绾瓮ㄟ^(guò)緩存和對(duì)象創(chuàng)建機(jī)制將數(shù)據(jù)庫(kù)結(jié)果集高效地映射為Java對(duì)象,文章通過(guò)實(shí)際的數(shù)據(jù)庫(kù)示例和偽代碼示例,展示了這兩個(gè)標(biāo)簽在一對(duì)多和一對(duì)一關(guān)系中的具體工作方式

引言

在 MyBatis 中,<collection><association> 標(biāo)簽用于處理一對(duì)多和一對(duì)一的關(guān)系。

這兩個(gè)標(biāo)簽在底層通過(guò)緩存、對(duì)象創(chuàng)建和反射機(jī)制,將數(shù)據(jù)庫(kù)結(jié)果集高效地映射為 Java 對(duì)象。

本文將重點(diǎn)探討這兩個(gè)標(biāo)簽的底層實(shí)現(xiàn)原理,并結(jié)合實(shí)際的數(shù)據(jù)庫(kù)示例說(shuō)明其工作機(jī)制。

1. Collection 的底層映射原理

1.1 一對(duì)多映射場(chǎng)景

<collection> 標(biāo)簽主要用于表示一對(duì)多關(guān)系的映射。

典型的一對(duì)多場(chǎng)景是在一個(gè)表中有重復(fù)的主對(duì)象記錄(如用戶),但每個(gè)主對(duì)象包含多個(gè)子對(duì)象(如訂單)。

示例數(shù)據(jù)庫(kù)結(jié)構(gòu)

假設(shè)我們有以下結(jié)果集,表示用戶和訂單的關(guān)系:

user_idusernameorder_idorder_date
1Alice1012023-01-01
1Alice1022023-02-01
2Bob1032023-03-01

這個(gè)數(shù)據(jù)表示,用戶 Alice 有兩個(gè)訂單,用戶 Bob 有一個(gè)訂單。我們希望將其映射為一個(gè) User 對(duì)象,每個(gè)用戶對(duì)象包含一個(gè)訂單集合。

MyBatis 映射配置

<resultMap id="userResultMap" type="com.example.User">
    <id property="userId" column="user_id"/>
    <result property="username" column="username"/>
    <collection property="orders" ofType="com.example.Order">
        <id property="orderId" column="order_id"/>
        <result property="orderDate" column="order_date"/>
    </collection>
</resultMap>

在這個(gè)映射中,<collection> 標(biāo)簽表示用戶對(duì)象 User 可能包含多個(gè) Order 對(duì)象,ofType 定義了集合中元素的類型。

1.2 底層映射機(jī)制

結(jié)果集處理

當(dāng)執(zhí)行 SQL 查詢時(shí),MyBatis 會(huì)獲取完整的結(jié)果集。由于用戶可能有多個(gè)訂單,查詢結(jié)果會(huì)包含重復(fù)的 user_idusername。

主對(duì)象緩存處理

MyBatis 使用主鍵 user_id 來(lái)判斷是否已經(jīng)創(chuàng)建了對(duì)應(yīng)的 User 對(duì)象(如果沒(méi)有主鍵, 會(huì)使用其他鍵來(lái)模擬唯一鍵)。

  • 如果 user_id 相同,表示當(dāng)前行屬于同一個(gè)用戶,則重用該用戶對(duì)象。
  • 如果 user_id 不同,MyBatis 會(huì)創(chuàng)建新的 User 對(duì)象。

集合屬性映射

對(duì)于每一行的訂單信息(order_idorder_date),MyBatis 會(huì)為當(dāng)前的用戶創(chuàng)建新的 Order 對(duì)象,并將其添加到用戶的 orders 集合中。

對(duì)象重用與集合管理

通過(guò)緩存機(jī)制,MyBatis 確保每個(gè)用戶只創(chuàng)建一次,而訂單則根據(jù)不同的 order_id 創(chuàng)建。對(duì)于相同的用戶,每個(gè)訂單行都會(huì)被添加到 orders 集合中。

底層邏輯代碼示例(偽代碼)

// 查詢用戶緩存處理
if (!cache.containsKey(userId)) {
    User user = new User();
    user.setUserId(resultSet.getInt("user_id"));
    user.setUsername(resultSet.getString("username"));
    cache.put(userId, user);
}

// 處理訂單集合
Order order = new Order();
order.setOrderId(resultSet.getInt("order_id"));
order.setOrderDate(resultSet.getDate("order_date"));

// 將訂單添加到用戶的集合
user.getOrders().add(order);

MyBatis 會(huì)緩存用戶對(duì)象,并通過(guò) getOrders().add(order) 方法將每個(gè)新創(chuàng)建的訂單對(duì)象加入到用戶的訂單集合中。

2. Association 的底層映射原理

2.1 一對(duì)一映射場(chǎng)景

<association> 標(biāo)簽用于處理一對(duì)一或多對(duì)一的映射。在這種場(chǎng)景下,通常我們希望將兩個(gè)表的結(jié)果組合為一個(gè)主對(duì)象和一個(gè)關(guān)聯(lián)對(duì)象。例如,用戶和用戶詳情是一對(duì)一的關(guān)系。

示例數(shù)據(jù)庫(kù)結(jié)構(gòu)

假設(shè)我們有以下結(jié)果集,表示用戶及其詳細(xì)信息:

user_idusernamedetail_idageaddress
1Alice125Wonderland
2Bob230Wonderland

這個(gè)數(shù)據(jù)表示,每個(gè)用戶有一條與之關(guān)聯(lián)的詳細(xì)信息記錄。我們希望將其映射為 User 對(duì)象,其中包含一個(gè) UserDetail 對(duì)象。

MyBatis 映射配置

<resultMap id="userWithDetailResultMap" type="com.example.User">
    <id property="userId" column="user_id"/>
    <result property="username" column="username"/>
    <association property="detail" javaType="com.example.UserDetail">
        <id property="detailId" column="detail_id"/>
        <result property="age" column="age"/>
        <result property="address" column="address"/>
    </association>
</resultMap>

在這個(gè)映射中,<association> 標(biāo)簽用于將用戶與詳細(xì)信息關(guān)聯(lián)起來(lái),javaType 指定了 UserDetail 對(duì)象的類型。

2.2 底層映射機(jī)制

主對(duì)象創(chuàng)建與緩存

當(dāng)執(zhí)行查詢時(shí),MyBatis 會(huì)首先根據(jù) user_id 創(chuàng)建或查找緩存中的用戶對(duì)象。類似于 <collection>,如果用戶對(duì)象已經(jīng)存在,則不會(huì)重新創(chuàng)建。

關(guān)聯(lián)對(duì)象的映射

對(duì)于每一行,MyBatis 根據(jù) detail_id 創(chuàng)建 UserDetail 對(duì)象,并通過(guò) MetaObject 機(jī)制,將查詢結(jié)果的 ageaddress 列映射到 UserDetail 對(duì)象中。

關(guān)聯(lián)對(duì)象賦值

一旦 UserDetail 對(duì)象創(chuàng)建完成,MyBatis 會(huì)將其賦值給 User 對(duì)象的 detail 屬性。這是通過(guò)反射完成的。

底層邏輯代碼示例(偽代碼)

// 用戶緩存處理
User user = cache.get(userId);

// 創(chuàng)建并映射用戶詳細(xì)信息
UserDetail detail = new UserDetail();
detail.setDetailId(resultSet.getInt("detail_id"));
detail.setAge(resultSet.getInt("age"));
detail.setAddress(resultSet.getString("address"));

// 將詳細(xì)信息賦值給用戶對(duì)象
user.setDetail(detail);

MyBatis 在映射時(shí)會(huì)通過(guò) MetaObject 訪問(wèn) User 對(duì)象的 detail 屬性,并使用反射為其賦值。這個(gè)過(guò)程使得每個(gè)用戶對(duì)象都能夠正確關(guān)聯(lián)其詳細(xì)信息。

3. 總結(jié)

MyBatis 中的 <collection><association> 標(biāo)簽通過(guò)緩存、反射與對(duì)象創(chuàng)建機(jī)制,完成數(shù)據(jù)庫(kù)結(jié)果集到 Java 對(duì)象的映射。在處理一對(duì)多和一對(duì)一關(guān)系時(shí),這兩個(gè)標(biāo)簽的底層機(jī)制可以高效地組織復(fù)雜的對(duì)象結(jié)構(gòu)。

  • <collection> 標(biāo)簽:通過(guò)主對(duì)象的緩存和子對(duì)象集合的動(dòng)態(tài)添加,實(shí)現(xiàn)了復(fù)雜的一對(duì)多關(guān)系的映射。
  • <association> 標(biāo)簽:通過(guò)關(guān)聯(lián)對(duì)象的創(chuàng)建和屬性映射,實(shí)現(xiàn)了一對(duì)一或多對(duì)一的關(guān)聯(lián)映射。

理解這些底層機(jī)制能夠幫助開(kāi)發(fā)者優(yōu)化查詢性能,并更好地設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu),充分發(fā)揮 MyBatis 的 ORM 功能。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java Lambda表達(dá)式的方法引用和構(gòu)造器引用實(shí)例分析

    Java Lambda表達(dá)式的方法引用和構(gòu)造器引用實(shí)例分析

    這篇文章主要介紹了Java Lambda表達(dá)式的方法引用和構(gòu)造器引用,結(jié)合實(shí)例形式分析了Lambda表達(dá)式的方法引用和構(gòu)造器引用相關(guān)原理、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-09-09
  • Spring,hibernate,struts經(jīng)典面試筆試題(含答案)

    Spring,hibernate,struts經(jīng)典面試筆試題(含答案)

    這篇文章主要介紹了Spring,hibernate,struts經(jīng)典面試筆試題極其參考含答案,涉及SSH基本概念,原理與使用技巧,需要的朋友可以參考下
    2016-03-03
  • SpringBoot中的bean管理示例詳解

    SpringBoot中的bean管理示例詳解

    這篇文章主要介紹了SpringBoot中的bean管理,本文結(jié)合示例代碼給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-06-06
  • Spring如何實(shí)現(xiàn)輸出帶動(dòng)態(tài)標(biāo)簽的日志

    Spring如何實(shí)現(xiàn)輸出帶動(dòng)態(tài)標(biāo)簽的日志

    文章介紹了如何通過(guò)動(dòng)態(tài)標(biāo)簽日志實(shí)現(xiàn),解決了部分業(yè)務(wù)代碼在多個(gè)模塊中調(diào)用時(shí)日志無(wú)法直觀看出來(lái)源的問(wèn)題,主要通過(guò)ThreadLocal存儲(chǔ)業(yè)務(wù)標(biāo)簽,并在日志輸出時(shí)插入該標(biāo)簽,實(shí)現(xiàn)日志的動(dòng)態(tài)標(biāo)簽功能,感興趣的朋友一起看看吧
    2024-12-12
  • Java BufferedReader相關(guān)源碼實(shí)例分析

    Java BufferedReader相關(guān)源碼實(shí)例分析

    這篇文章主要介紹了Java BufferedReader相關(guān)源碼實(shí)例分析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-10-10
  • jdk17+springboot使用webservice的踩坑實(shí)戰(zhàn)記錄

    jdk17+springboot使用webservice的踩坑實(shí)戰(zhàn)記錄

    這篇文章主要給大家介紹了關(guān)于jdk17+springboot使用webservice踩坑的相關(guān)資料,網(wǎng)上很多教程是基于jdk8的,所以很多在17上面跑不起來(lái),折騰兩天,直接給答案,需要的朋友可以參考下
    2024-01-01
  • Springboot如何通過(guò)filter修改Header的值

    Springboot如何通過(guò)filter修改Header的值

    這篇文章主要介紹了Springboot如何通過(guò)filter修改Header的值問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java非法字符: ‘\ufeff‘問(wèn)題及說(shuō)明

    Java非法字符: ‘\ufeff‘問(wèn)題及說(shuō)明

    這篇文章主要介紹了Java非法字符: ‘\ufeff‘問(wèn)題及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-02-02
  • 基于module-info.class的問(wèn)題

    基于module-info.class的問(wèn)題

    這篇文章主要介紹了基于module-info.class的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • java File類重要方法以及如何操作文件詳解

    java File類重要方法以及如何操作文件詳解

    這篇文章主要為大家介紹了java File類重要方法以及如何操作文件詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-06-06

最新評(píng)論

雷山县| 韩城市| 邢台市| 虞城县| 岗巴县| 龙江县| 满城县| 锡林浩特市| 汾阳市| 聊城市| 阳春市| 新昌县| 崇阳县| 阳曲县| 白玉县| 晴隆县| 香港 | 霞浦县| 定西市| 常山县| 商都县| 屯留县| 乐清市| 宁晋县| 象州县| 哈巴河县| 安乡县| 无锡市| 武安市| 腾冲县| 宝鸡市| 原平市| 新兴县| 崇礼县| 宜阳县| 宝山区| 丰城市| 仁寿县| 盐池县| 江西省| 蓬莱市|