MyBatis中<collection>標(biāo)簽的多種用法
在 MyBatis 中,<collection> 標(biāo)簽是處理一對(duì)多(One-to-Many)關(guān)系的關(guān)鍵工具,它能夠?qū)⒉樵兘Y(jié)果巧妙地映射到 Java 對(duì)象的集合屬性中。以下是 <collection> 的不同用法及其示例,結(jié)合知識(shí)庫(kù)中的信息整理如下:
一、嵌套查詢(Nested Select)
通過(guò) select 屬性引用另一個(gè) SQL 查詢,根據(jù)主表的某一列(如 id)作為參數(shù),查詢子表的集合數(shù)據(jù)。
特點(diǎn)
每條主記錄會(huì)觸發(fā)一次子查詢(可能導(dǎo)致 N+1 問(wèn)題)。
適合數(shù)據(jù)量較小或需要遞歸查詢的場(chǎng)景。
示例代碼
<!-- 主表的resultMap -->
<resultMap id="UserMap" type="User">
<id property="id" column="id"/>
<result property="username" column="username"/>
<!-- 集合屬性:permissions -->
<collection
property="permissions"
ofType="Permission"
select="com.example.mapper.PermissionMapper.selectByUserId"
column="id"
/>
</resultMap>
<!-- 主表的查詢SQL -->
<select id="selectUser" resultMap="UserMap">
SELECT id, username FROM users WHERE id = #{id}
</select>
<!-- 子查詢(PermissionMapper.xml) -->
<select id="selectByUserId" resultType="Permission">
SELECT * FROM permissions WHERE user_id = #{id}
</select>解釋
property="permissions":映射到User類的permissions集合屬性。ofType="Permission":指定集合元素的類型。select="...":引用子查詢的 Mapper 方法。column="id":將主表的id作為參數(shù)傳遞給子查詢。
二、嵌套結(jié)果(Nested Results)
通過(guò) column 和 ofType 直接映射 JOIN 查詢的結(jié)果,避免多次查詢數(shù)據(jù)庫(kù)。
特點(diǎn)
通過(guò) JOIN 一次性獲取所有數(shù)據(jù),減少查詢次數(shù)。
需要處理重復(fù)數(shù)據(jù)(主表字段會(huì)被重復(fù),需通過(guò)
columnPrefix區(qū)分)。
示例代碼
<!-- 主表的resultMap -->
<resultMap id="UserMap" type="User">
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<!-- 集合屬性:orders -->
<collection
property="orders"
ofType="Order"
columnPrefix="order_"
>
<id property="orderId" column="order_id"/>
<result property="amount" column="amount"/>
</collection>
</resultMap>
<!-- 主表的查詢SQL(使用JOIN) -->
<select id="selectUserWithOrders" resultMap="UserMap">
SELECT
u.id AS user_id,
u.username,
o.id AS order_id,
o.amount
FROM users u
LEFT JOIN orders o ON u.id = o.user_id
WHERE u.id = #{id}
</select>解釋
columnPrefix="order_":將子表字段名前綴(如order_id)與主表字段區(qū)分開(kāi)。<collection>內(nèi)部定義子表字段的映射規(guī)則。主表字段(如
user_id)和子表字段(如order_id)通過(guò)別名區(qū)分。
三、遞歸查詢(Recursive Query)
用于構(gòu)建層級(jí)結(jié)構(gòu)(如樹(shù)形菜單、權(quán)限結(jié)構(gòu)),通過(guò) <collection> 自引用實(shí)現(xiàn)遞歸。
特點(diǎn)
通過(guò)
select屬性引用自身或同級(jí)的查詢方法,形成遞歸調(diào)用。適用于組織結(jié)構(gòu)、分類樹(shù)等場(chǎng)景。
示例代碼
<!-- 處理樹(shù)形結(jié)構(gòu)的resultMap -->
<resultMap id="CategoryMap" type="Category">
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="parentId" column="parent_id"/>
<!-- 遞歸查詢子節(jié)點(diǎn) -->
<collection
property="children"
ofType="Category"
select="selectCategoriesByParentId"
column="id"
/>
</resultMap>
<!-- 查詢父節(jié)點(diǎn)的子節(jié)點(diǎn) -->
<select id="selectCategoriesByParentId" resultMap="CategoryMap">
SELECT * FROM categories WHERE parent_id = #{id}
</select>解釋
column="id":將當(dāng)前節(jié)點(diǎn)的id作為父節(jié)點(diǎn) ID 傳遞給子查詢。<collection>引用同一個(gè) Mapper 中的selectCategoriesByParentId方法,形成遞歸。直到?jīng)]有子節(jié)點(diǎn)時(shí)停止遞歸。
四、使用 column 傳遞多個(gè)參數(shù)
當(dāng)子查詢需要多個(gè)參數(shù)時(shí),可以通過(guò)表達(dá)式指定多個(gè)列。
語(yǔ)法
column="{param1=column1, param2=column2}"示例代碼
<collection
property="items"
ofType="Item"
select="com.example.mapper.ItemMapper.selectItemsByUserAndDate"
column="{userId=id, date=createTime}"
/>解釋
子查詢
selectItemsByUserAndDate需要兩個(gè)參數(shù):userId和date。column表達(dá)式將主表的id映射為userId,createTime映射為date。
五、javaType 和 ofType 的區(qū)別
ofType:必須指定,用于定義集合中元素的類型(如Permission)。javaType:可選,指定集合的類型(如ArrayList)。若不指定,MyBatis 默認(rèn)使用List。
示例
<!-- 顯式指定javaType -->
<collection
property="permissions"
javaType="ArrayList"
ofType="Permission"
select="..."
column="..."
/>總結(jié):不同場(chǎng)景的適用性
| 場(chǎng)景 | 推薦用法 | 優(yōu)缺點(diǎn) |
|---|---|---|
| 簡(jiǎn)單的一對(duì)多關(guān)系 | 嵌套查詢(select) | 簡(jiǎn)單易用,但可能引發(fā) N+1 問(wèn)題 |
| 需要 JOIN 一次性獲取數(shù)據(jù) | 嵌套結(jié)果(columnPrefix) | 減少查詢次數(shù),但需處理重復(fù)字段和復(fù)雜 SQL |
| 樹(shù)形結(jié)構(gòu)(如菜單、分類) | 遞歸查詢(自引用) | 簡(jiǎn)潔且可自動(dòng)構(gòu)建層級(jí),但需注意性能(尤其數(shù)據(jù)量大時(shí)) |
| 需要傳遞多個(gè)參數(shù) | column 表達(dá)式 | 靈活傳遞多個(gè)參數(shù),但需確保子查詢參數(shù)匹配 |
通過(guò)合理選擇 <collection> 的用法,可以高效地處理 MyBatis 中的一對(duì)多映射需求。
到此這篇關(guān)于MyBatis中<collection>標(biāo)簽的多種用法的文章就介紹到這了,更多相關(guān)MyBatis collection標(biāo)簽內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mybatis collection關(guān)聯(lián)查詢多個(gè)參數(shù)方式
- MyBatis使用嵌套查詢collection和association的實(shí)現(xiàn)
- mybatis?resultMap之collection聚集兩種實(shí)現(xiàn)方式
- mybatis中association和collection的使用與區(qū)別
- MyBatis的collection和association的使用解讀
- Mybatis中一對(duì)多(collection)和一對(duì)一(association)的組合查詢使用
- Mybatis使用Collection屬性的示例代碼
- Mybatis的collection三層嵌套查詢方式(驗(yàn)證通過(guò))
- mybatis?collection和association的區(qū)別解析
相關(guān)文章
Spring?Boot與JWT和Shiro整合實(shí)踐步驟(非常詳細(xì)!)
這篇文章主要介紹了Spring?Boot與JWT和Shiro整合的相關(guān)資料,將Shiro、Spring Boot和JWT集成在一起,可以大大提高應(yīng)用程序的安全性,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2025-09-09
MybatisPlus使用idworker解決雪花算法重復(fù)
本文主要介紹了MybatisPlus使用idworker解決雪花算法重復(fù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-02-02
SpringBoot定時(shí)任務(wù)實(shí)現(xiàn)數(shù)據(jù)庫(kù)數(shù)據(jù)同步全過(guò)程
文章詳細(xì)介紹了從簡(jiǎn)單到企業(yè)級(jí)數(shù)據(jù)庫(kù)同步需求的技術(shù)方案,包括選型、實(shí)現(xiàn)步驟、優(yōu)化方案、異常處理策略、生產(chǎn)環(huán)境配置建議等2025-12-12
dubbo擴(kuò)展點(diǎn)AOP切面功能擴(kuò)展示例詳解
這篇文章主要為大家介紹了dubbo擴(kuò)展點(diǎn)AOP切面功能擴(kuò)展示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
如何基于java向mysql數(shù)據(jù)庫(kù)中存取圖片
這篇文章主要介紹了如何基于java向mysql數(shù)據(jù)庫(kù)中存取圖片,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02
tk.mybatis實(shí)現(xiàn)uuid主鍵生成的示例代碼
本文主要介紹了tk.mybatis實(shí)現(xiàn)uuid主鍵生成的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-12-12
SpringBoot如何讀取配置文件參數(shù)并全局使用
這篇文章主要介紹了SpringBoot如何讀取配置文件參數(shù)并全局使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
elasticsearch索引創(chuàng)建create?index集群matedata更新
這篇文章主要介紹了elasticsearch索引創(chuàng)建create?index及集群matedata更新,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-04-04
登錄EasyConnect后無(wú)法通過(guò)jdbc訪問(wèn)服務(wù)器數(shù)據(jù)庫(kù)問(wèn)題的解決方法
描述一下近期使用EasyConnect遇到的問(wèn)題,下面這篇文章主要給大家介紹了關(guān)于登錄EasyConnect后無(wú)法通過(guò)jdbc訪問(wèn)服務(wù)器數(shù)據(jù)庫(kù)問(wèn)題的解決方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-02-02

