MyBatis中<collection>標(biāo)簽的多種用法
在 MyBatis 中,<collection>
標(biāo)簽是處理一對(duì)多(One-to-Many)關(guān)系的關(guān)鍵工具,它能夠?qū)⒉樵?xún)結(jié)果巧妙地映射到 Java 對(duì)象的集合屬性中。以下是 <collection>
的不同用法及其示例,結(jié)合知識(shí)庫(kù)中的信息整理如下:
一、嵌套查詢(xún)(Nested Select)
通過(guò) select
屬性引用另一個(gè) SQL 查詢(xún),根據(jù)主表的某一列(如 id
)作為參數(shù),查詢(xún)子表的集合數(shù)據(jù)。
特點(diǎn)
每條主記錄會(huì)觸發(fā)一次子查詢(xún)(可能導(dǎo)致 N+1 問(wèn)題)。
適合數(shù)據(jù)量較小或需要遞歸查詢(xún)的場(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> <!-- 主表的查詢(xún)SQL --> <select id="selectUser" resultMap="UserMap"> SELECT id, username FROM users WHERE id = #{id} </select> <!-- 子查詢(xún)(PermissionMapper.xml) --> <select id="selectByUserId" resultType="Permission"> SELECT * FROM permissions WHERE user_id = #{id} </select>
解釋
property="permissions"
:映射到User
類(lèi)的permissions
集合屬性。ofType="Permission"
:指定集合元素的類(lèi)型。select="..."
:引用子查詢(xún)的 Mapper 方法。column="id"
:將主表的id
作為參數(shù)傳遞給子查詢(xún)。
二、嵌套結(jié)果(Nested Results)
通過(guò) column
和 ofType
直接映射 JOIN 查詢(xún)的結(jié)果,避免多次查詢(xún)數(shù)據(jù)庫(kù)。
特點(diǎn)
通過(guò) JOIN 一次性獲取所有數(shù)據(jù),減少查詢(xún)次數(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> <!-- 主表的查詢(xún)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ū)分。
三、遞歸查詢(xún)(Recursive Query)
用于構(gòu)建層級(jí)結(jié)構(gòu)(如樹(shù)形菜單、權(quán)限結(jié)構(gòu)),通過(guò) <collection>
自引用實(shí)現(xiàn)遞歸。
特點(diǎn)
通過(guò)
select
屬性引用自身或同級(jí)的查詢(xún)方法,形成遞歸調(diào)用。適用于組織結(jié)構(gòu)、分類(lèi)樹(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"/> <!-- 遞歸查詢(xún)子節(jié)點(diǎn) --> <collection property="children" ofType="Category" select="selectCategoriesByParentId" column="id" /> </resultMap> <!-- 查詢(xún)父節(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 傳遞給子查詢(xún)。<collection>
引用同一個(gè) Mapper 中的selectCategoriesByParentId
方法,形成遞歸。直到?jīng)]有子節(jié)點(diǎn)時(shí)停止遞歸。
四、使用 column 傳遞多個(gè)參數(shù)
當(dāng)子查詢(xún)需要多個(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}" />
解釋
子查詢(xún)
selectItemsByUserAndDate
需要兩個(gè)參數(shù):userId
和date
。column
表達(dá)式將主表的id
映射為userId
,createTime
映射為date
。
五、javaType 和 ofType 的區(qū)別
ofType
:必須指定,用于定義集合中元素的類(lèi)型(如Permission
)。javaType
:可選,指定集合的類(lèi)型(如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)系 | 嵌套查詢(xún)(select) | 簡(jiǎn)單易用,但可能引發(fā) N+1 問(wèn)題 |
需要 JOIN 一次性獲取數(shù)據(jù) | 嵌套結(jié)果(columnPrefix) | 減少查詢(xún)次數(shù),但需處理重復(fù)字段和復(fù)雜 SQL |
樹(shù)形結(jié)構(gòu)(如菜單、分類(lèi)) | 遞歸查詢(xún)(自引用) | 簡(jiǎn)潔且可自動(dòng)構(gòu)建層級(jí),但需注意性能(尤其數(shù)據(jù)量大時(shí)) |
需要傳遞多個(gè)參數(shù) | column 表達(dá)式 | 靈活傳遞多個(gè)參數(shù),但需確保子查詢(xún)參數(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)查詢(xún)多個(gè)參數(shù)方式
- MyBatis使用嵌套查詢(xún)collection和association的實(shí)現(xiàn)
- mybatis?resultMap之collection聚集兩種實(shí)現(xiàn)方式
- mybatis中association和collection的使用與區(qū)別
- MyBatis的collection和association的使用解讀
- Mybatis中一對(duì)多(collection)和一對(duì)一(association)的組合查詢(xún)使用
- Mybatis使用Collection屬性的示例代碼
- Mybatis的collection三層嵌套查詢(xún)方式(驗(yàn)證通過(guò))
- mybatis?collection和association的區(qū)別解析
相關(guān)文章
Springboot整合quartz實(shí)現(xiàn)多個(gè)定時(shí)任務(wù)實(shí)例
這篇文章主要介紹了Springboot整合quartz實(shí)現(xiàn)多個(gè)定時(shí)任務(wù)代碼實(shí)例,Quartz?是一款功能強(qiáng)大的開(kāi)源任務(wù)調(diào)度框架,幾乎可以集成到任何?Java?應(yīng)用程序中,Quartz?可用于創(chuàng)建簡(jiǎn)單或復(fù)雜的任務(wù)調(diào)度,用以執(zhí)行數(shù)以萬(wàn)計(jì)的任務(wù),需要的朋友可以參考下2023-08-08Java如何利用線(xiàn)程池和Redis實(shí)現(xiàn)高效數(shù)據(jù)入庫(kù)
文章介紹了如何利用線(xiàn)程池和Redis在高并發(fā)環(huán)境中實(shí)現(xiàn)高效的數(shù)據(jù)入庫(kù),通過(guò)將數(shù)據(jù)首先存儲(chǔ)在Redis緩存中,然后利用線(xiàn)程池定期批量入庫(kù)處理,確保系統(tǒng)的性能和穩(wěn)定性,主要組件包括BatchDataStorageService、CacheService和RedisUtils等2025-02-02SpringBoot中將@Bean方法解析為BeanDefinition詳解
這篇文章主要介紹了SpringBoot中將@Bean方法解析為BeanDefinition詳解,得到的BeanDefinition是ConfigurationClassBeanDefinition類(lèi)型,會(huì)為BeanDefinition設(shè)置factoryMethodName,這意味著當(dāng)實(shí)例化這個(gè)bean的時(shí)候?qū)⒉捎霉S(chǎng)方法,需要的朋友可以參考下2023-12-12MybatisPlus實(shí)現(xiàn)數(shù)據(jù)權(quán)限隔離的示例詳解
Mybatis Plus對(duì)Mybatis做了無(wú)侵入的增強(qiáng),非常的好用,今天就給大家介紹它的其中一個(gè)實(shí)用功能:數(shù)據(jù)權(quán)限插件,感興趣的可以跟隨小編一起了解下2024-04-04Java命令行運(yùn)行錯(cuò)誤之找不到或無(wú)法加載主類(lèi)問(wèn)題的解決方法
這篇文章主要給大家介紹了關(guān)于Java命令行運(yùn)行錯(cuò)誤之找不到或無(wú)法加載主類(lèi)問(wèn)題的解決方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2022-01-01