MyBatis-Plus(六):SQL结果重复字段合并与一对多映射

大家好,我是欧阳方超,微信公众号同名。

在这里插入图片描述

1 概述

在实际开发中我们经常遇到这样的场景,SQL查询结果中主表字段存在重复,因为它关联了多条子表数据,我们希望在Java端把这些重复的主表字段合并成一个对象,同时把对应的不重复的子表数据放到一个List集合中。这种一对多的映射关系是MyBatis-Plus(Mybatis)中非常典型的场景。本文将讲述如何在MyBatis-Plus的XML配置中实现这一功能。

2 场景描述

重复字段与一对多映射。假设有这样两个表,orders(订单表),存储订单信息,order_items(订单明细表),存储订单对应的商品明细。一条订单可能对应多条订单明细,因此SQL查询时,订单信息回重复出现多次,导致查询结果中主表字段(订单)重复,子表字段(商品明细)不同。

order_idorder_nameitem_iditem_name
1订单A101苹果
1订单A102香蕉
12订单B103橙子

希望在Java程序中得到这样的东西:
一个订单对象Order,包含订单id和名称;
订单对象中有一个items属性,是一个List,包含所有该订单的商品明细。

3 解决方案核心思路

在SQL层面,使用join查询主表和子表,返回多行数据,主表字段重复。
在MyBatis XML中,使用resultMap定义映射规则,利用collection标签实现一对多关系,将子表数据映射成List集合。
MyBatis会根据主键自动合并重复的主表对象,避免重复创建,子表数据放入结合。

4 实现方式

4.1 定义Java实体类

public class Order {
    private Long orderId;
    private String orderName;
    private List<OrderItem> items;  // 一对多关联集合

    // getter和setter省略
}

public class OrderItem {
    private Long itemId;
    private String itemName;

    // getter和setter省略
}

4.2 编写Mapper XML

<resultMap id="OrderResultMap" type="Order">
    <!-- 主表主键 -->
    <id property="orderId" column="order_id"/>
    <result property="orderName" column="order_name"/>
    
    <!-- 一对多集合映射 -->
    <collection property="items" ofType="OrderItem">
        <id property="itemId" column="item_id"/>
        <result property="itemName" column="item_name"/>
    </collection>
</resultMap>

<select id="selectOrdersWithItems" resultMap="OrderResultMap">
    SELECT o.order_id, o.order_name, i.item_id, i.item_name
    FROM orders o
    LEFT JOIN order_items i ON o.order_id = i.order_id
</select>

4.3 Mapper接口方法

List<Order> selectOrdersWithItems();

调用该方法即可获得订单列表,每个订单对象的items属性是对应的商品明细集合。

5 现象与原理

SQL返回多行,主表字段重复,子表字段不同。MyBatis根据id指定的主键字段,自动合并主表对象,避免重复创建。将对应的子表数据映射为子对象,放入主对象的集合属性中。Java程序中得到结构清晰的一对多对象模型,方便业务处理。

6 总结

通过resultMap和collection标签,可以轻松实现SQL查询中重复字段的合并和一对多数据的List映射。这种方式不仅代码简洁,且符合面向对象设计,极大提升开发效率和代码维可维护性。
我是欧阳方超,把事情做好了自然就有兴趣了,如果你喜欢我的文章,欢迎点赞、转发、评论加关注。我们下次见。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值