Mybatis一对多查询 ,以及会遇到的各种问题解答

业务场景

  有时候前端需要表格里面嵌套表格的情况,用以展示更加详细的信息,提高用户体验。
例如:
在这里插入图片描述

实体类,数据库

而此时就需要后端返回复杂的数据结构实体类中嵌套实体类的情况了。
例如:主表 PlnOrderPool.java(为节省空间 实体类中都未写get,set方法。)
在这里插入图片描述

附表:PlnOrderPoolDetail.java
在这里插入图片描述

订单主表:
订单主表
订单附表:
在这里插入图片描述

方法1:连表查询,用ResultMap映射

注意事项:见图片中
在这里插入图片描述
图片上最后的where是没有的(sorry)
代码:

<resultMap id="orderAndDetail" type="org.jeecg.modules.pln.infrastructure.dao.entity.PlnOrderPool">
        <id property="orderNo" column="order_no"/>
        <result property="name" column="name"/>
        <result property="customerName" column="customer_name"/>
        <collection property="detailList" ofType="org.jeecg.modules.pln.infrastructure.dao.entity.PlnOrderPoolDetail">
            <id property="id" column="d_id"/>
            <result property="deliverTime" column="deliver_time"/>
            <result property="deliverNum" column="deliver_num"/>
        </collection>
    </resultMap>
    <select id="getOrderAndDetail" resultMap="orderAndDetail">
        SELECT
            pop.order_no,
            pop.NAME,
            pop.customer_name,
            popd.id d_id,
            popd.deliver_time,
            popd.deliver_num
        FROM
	        pln_order_pool pop
	        LEFT JOIN pln_order_pool_detail popd ON pop.order_no = popd.order_id
    </select>

结果:

{
    "message": "success",
    "code": 0,
    "data": [
        {
            "orderNo": "ORDER2022092900005",
            "customerName": "上汽大通",
            "name": "冷却模块",
            "detailList": [
                {
                    "id": "1575280472165048321",
                    "deliverNum": 60.0,
                    "deliverTime": "2022-10-07",
                }
            ]
        },
        {
            "orderNo": "ORDER2022092900006",
            "customerName": "上汽大通",
            "name": "冷却模块",
            "detailList": [
                {
                    "id": "1575280472177631234",
                    "deliverNum": 80.0,
                    "deliverTime": "2022-10-08",
                },
                {
                    "id": "1575280472177631235",
                    "deliverNum": 78.0,
                    "deliverTime": "2022-10-19",
                }
            ]
        },
        {
            "orderNo": "ORDER2022092900007",
            "customerName": "无通",
            "name": "散成",
            "detailList": [
                {
                    "id": "1575280472177631236",
                    "deliverNum": 240.0,
                    "deliverTime": "2022-10-07",
                },
                {
                    "id": "1575280472186019841",
                    "deliverNum": 240.0,
                    "deliverTime": "2022-10-08",
                },
                {
                    "id": "1575280472186019842",
                    "deliverNum": 240.0,
                    "deliverTime": "2022-10-09",
                },
                {
                    "id": "1575280472186019843",
                    "deliverNum": 240.0,
                    "deliverTime": "2022-10-10",
                }
            ]
        }
    ]
}

原理:先查询出所有数据,然后根据你规定的resultMap映射关系,去组建数据结构。 property 对应你的实体类中的属性名,column 对应你sql查出来的字段名。
并且他是根据你的<id property="orderNo" column="order_no"/> 去确定谁能代表一条主表数据,类似于分组。
优点:效率较高只需要一次查库操作,操作方便过滤条件写在一个sql中
缺点:根据主表进行分页查询比较难以实现

方法2:子查询进行映射

注意事项:
1:子查询collection中column中的值写法;
  column值有两种写法:
(一),如果下图中1和4的值相同,可以直接写一个,类似于:column="xxx"
(二),下图中写法,如果有多个参数可用逗号分隔,例如:column="{d_orderNo=order_no,xxx=xxx,...}"
2:select 中的值应该为:子查询在mapper中的全路径。
在这里插入图片描述
代码:

<resultMap id="orderAll" type="org.jeecg.modules.pln.infrastructure.dao.entity.PlnOrderPool">
        <id property="orderNo" column="order_no" />
        <result property="name" column="name" />
        <result property="customerName" column="customer_name" />
        <collection property="detailList"
                    ofType="org.jeecg.modules.pln.infrastructure.dao.entity.PlnOrderPoolDetail"
                    select="org.jeecg.modules.pln.infrastructure.dao.mapper.PlnOrderPoolMapper.getDetailAll"
                    column="{d_orderNo=order_no}"></collection>
    </resultMap>
<!--    主表的在resultMap中标识了id的必须唯一-->
    <select id="getAll" resultMap="orderAll">
        select order_no,name,customer_name from pln_order_pool where order_no = #{orderNo}
    </select>
    <select id="getDetailAll" resultType="org.jeecg.modules.pln.infrastructure.dao.entity.PlnOrderPoolDetail">
        select order_id,deliver_time,deliver_num from pln_order_pool_detail where order_id = #{d_orderNo}
    </select>

原理:这种写法是先去查询主表然后再去根据主表中的条件去查询附表,是要进行n+1次数据库交互的。
缺点:要进行n+1次数据库交互,效率低。子查询传参过滤比较复杂
优点:无论是分页还是普通查询都能满足

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值