Mybatis一对多查询的两种姿势(值得收藏)

网友投稿 908 2023-01-21

Mybatis一对多查询的两种姿势(值得收藏)

Mybatis一对多查询的两种姿势(值得收藏)

前言

最近碰到了Mybatis一对多查询的场景,在这里总结对比下常见的两种实现方式。

本文以常见的订单表和订单详情表来举例说明;

数据库表准备

订单表 tbl_order

订单详情表 tlb_order_detail

ps: 一个订单关联多个订单详情,通过order_no订单号关联;

实例演示

方法一:联合查询ResultMap映射

sql直接关联查询,然后结果集通过resultMap的collection映射

例如 查询订单列表,包括订单详情

Order.java 中新增字段orderDetailList,用于存详情列表

public class Order {

private Integer id;

private String orderNo;

private Date orderTime;

private Date payTime;

private String remark;

/**订单详情*/

private List orderDetailList;

//省略get、set

OrderMapper.java 新增查询方法

List queryOrderList(Map map);

OrderMapper.xml

SELECT

o.*, d.id as d_id,d.order_no as d_order_no,d.good_name,d.good_id,d.good_count

FROM

tbl_order o

LEFT JOIN tbl_order_detail d ON d.order_no = o.order_no

where 1=1

and o.order_no = #{orderNo}

ORDER BY o.order_time desc

查询结果展示

[

  {

    "id": 2,

    "orderNo": "DD000002",

    "orderTime": "2021-05-09 12:25:57",

    "payTime": "2021-05-09 12:25:59",

    "remark": "2号订单",

    "orderDetailList": [

      {

        "id": 5,

        "orderNo": "DD000002",

        "goodName": "耳机",

        "goodId": 5,

        "goodCount": 1

      },

      {

        "id": 4,

        "orderNo": "DD000002",

        "goodName": "手机",

        "goodId": 4,

        "goodCount": 1

      }

    ]

  },

  {

    "id": 1,

    "orderNo": "DD000001",

    "orderTime": "2021-05-09 12:25:37",

    "payTime": "2021-05-09 12:25:41",

    "remark": "1号订单",

    "orderDetailList": [

      {

        "id": 2,

        "orderNo": "DD000001",

        "goodName": "饮料",

        "goodId": 2,

        "goodCount": 2

      },

      {

        "id": 1,

        "orderNo": "DD000001",

        "goodName": "瓜子",

        "goodId": 1,

        "goodCount": 1

      },

      {

        "id": 3,

        "orderNo": "DD000001",

        "goodName": "矿泉水",

        "goodId": 3,

        "goodCount": 2

      }

    ]

  }

]

原理:sql直接关联查询,然后结果集通过resultMap的collection映射,将order_detail表对应的字段映射到orderDetailList字段中。

优点:条件查询方便;无论是订单表还是详情表如果要进行一些条件过滤的话,非常方便,直接写在where中限制就行。

不足:因为是先关联查询,后映射;如果需要进行分页查询的话,这种方式就无法满足。主表2条数据,详情表5条数据,关联之后就是10条,无法得主表进行分页;解决方法,就是先给主表套个子查询limit分页后,然后结果集再跟详情表进行关联查询;

方法二:子查询映射

通过resultMap中collection标签的select属性去执行子查询

还以查询订单列表为例

OrderMapper.java

List queryOrderList2(Map map);

OrderMapper.xml

select="queryDetail" column="order_no">

select="queryDetail" column="order_no">

SELECT

o.*

FROM

tbl_order o

where 1=1

and o.order_no = #{orderNo}

ORDER BY o.order_time desc

SELECT

*

FROM

`tbl_order_detail` where order_no = #{order_no}

查询结果同上个例子一样;

原理:通过collection的select方法去调用子查询;所需参数通过column传递;

优点:无论是分页还是普通查询都能满足;主表增加过滤条件也很方便,直接在主查询的sql中增加where条件就行

缺点:子查询不好增加过滤条件;column只能传递主表已有的字段。下面提供解决方式;

ps:column传递多个参数 column=“{prop1=col1,prop2=col2}”

例如:实际场景中,详情表有个状态字段,只展示状态正常的详情,需要过滤详情记录。

本例子没有状态字段,就查询订单列表,详情中不展示瓜子,即详情记录中过滤掉good_id = 1的;

在上个例子基础上修改如下:

调用层传参

Map map = new HashMap();

map.put("goodId", 1);

orderMapper.queryOrderList2(map);

orderMapper.xml中增加传参过滤

展示结果如下:详情中已成功过滤掉瓜子;记住,过滤子查询不会影响主表记录;

[

  {

    "id": 2,

    "orderNo": "DD000002",

    "orderTime": "2021-05-09 12:25:57",

    "payTime": "2021-05-09 12:25:59",

    "remark": "2号订单",

    "orderDetailList": [

      {

        "id": 4,

        "orderNo": "DD000002",

        "goodName": "手机",

        "goodId": 4,

        "goodCount": 1

      },

      {

        "id": 5,

        "orderNo": "DD000002",

        "goodName": "耳机",

        "goodId": 5,

        "goodCount": 1

      }

    ]

  },

  {

    "id": 1,

    "orderNo": "DD000001",

    "orderTime": "2021-05-09 12:25:37",

    "payTime": "2021-05-09 12:25:41",

    "remark": "1号订单",

    "orderDetailList": [

      {

        "id": 2,

        "orderNo": "DD000001",

        "goodName": "饮料",

        "goodId": 2,

        "goodCount": 2

      },

      {

        "id": 3,

        "orderNo": "DD000001",

        "goodName": "矿泉水",

        "goodId": 3,

        "goodCount": 2

      }

    ]

  }

]

总结

方式

联合查询映射

子查询映射

原理

sql查询完成后再通过resultmap映射结果

主表的数据集循环调用子查询

分页

不支持分页查询,主表套子查询也能实现

支持分页

条件过滤

方便条件过滤

传参也能实现,复杂参数例如list不好传递给子查询 ;子查询过滤不影响主表数据

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:快应用开发(快应用开发车机快应用)
下一篇:移动应用开发平台(移动端应用开发)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~