java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > MyBatis  collection标签

MyBatis中<collection>标签的多种用法

作者:愿你天黑有灯下雨有伞

collection标签是处理一对多关系的关键工具,它能够将查询结果巧妙地映射到Java对象的集合属性中,本文主要介绍了MyBatis中<collection>标签的多种用法,感兴趣的可以了解一下

在 MyBatis 中,<collection> 标签是处理一对多(One-to-Many)关系的关键工具,它能够将查询结果巧妙地映射到 Java 对象的集合属性中。以下是 <collection> 的不同用法及其示例,结合知识库中的信息整理如下:

一、嵌套查询(Nested Select)

通过 select 属性引用另一个 SQL 查询,根据主表的某一列(如 id)作为参数,查询子表的集合数据。

特点

示例代码

<!-- 主表的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>

解释

二、嵌套结果(Nested Results)

通过 column 和 ofType 直接映射 JOIN 查询的结果,避免多次查询数据库。

特点

示例代码

<!-- 主表的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>

解释

三、递归查询(Recursive Query)

用于构建层级结构(如树形菜单、权限结构),通过 <collection> 自引用实现递归。

特点

示例代码

<!-- 处理树形结构的resultMap -->
<resultMap id="CategoryMap" type="Category">
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <result property="parentId" column="parent_id"/>
    <!-- 递归查询子节点 -->
    <collection 
        property="children" 
        ofType="Category" 
        select="selectCategoriesByParentId" 
        column="id"
    />
</resultMap>

<!-- 查询父节点的子节点 -->
<select id="selectCategoriesByParentId" resultMap="CategoryMap">
    SELECT * FROM categories WHERE parent_id = #{id}
</select>

解释

四、使用 column 传递多个参数

当子查询需要多个参数时,可以通过表达式指定多个列。

语法

column="{param1=column1, param2=column2}"

示例代码

<collection 
    property="items" 
    ofType="Item" 
    select="com.example.mapper.ItemMapper.selectItemsByUserAndDate" 
    column="{userId=id, date=createTime}"
/>

解释

五、javaType 和 ofType 的区别

示例

<!-- 显式指定javaType -->
<collection 
    property="permissions" 
    javaType="ArrayList" 
    ofType="Permission" 
    select="..." 
    column="..."
/>

总结:不同场景的适用性

场景推荐用法优缺点
简单的一对多关系嵌套查询(select)简单易用,但可能引发 N+1 问题
需要 JOIN 一次性获取数据嵌套结果(columnPrefix)减少查询次数,但需处理重复字段和复杂 SQL
树形结构(如菜单、分类)递归查询(自引用)简洁且可自动构建层级,但需注意性能(尤其数据量大时)
需要传递多个参数column 表达式灵活传递多个参数,但需确保子查询参数匹配

通过合理选择 <collection> 的用法,可以高效地处理 MyBatis 中的一对多映射需求。

到此这篇关于MyBatis中<collection>标签的多种用法的文章就介绍到这了,更多相关MyBatis  collection标签内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文