mybatise一对多关系查询时不能直接分页

MyBatis一对多分页
本文介绍在MyBatis中解决一对多关系查询时的分页问题,提供了一种通过计算副表记录数来调整RowBounds的方法,并讨论了另一种不使用collection映射的策略。

在mybatise应用时候我们经常会用到collection进行一对多映射,这时候分页就有了问题。
比如A表1条记录对应B表3条记录,这时候查询就是3条记录,但是实际上我们需要的只是1条。
解决方案:

一 提供一个工具方法生成新的RowBounds

核心思想:
1 计算主表对应副表的记录数List counts

2 计算页面大小pageSize,等于原pageSize+counts集合里面每个值的累加

3 设置偏移量

/**
     * mybatise一对多关系查询时不能直接分页,可以用此方法获取RowBounds对象。<br/>
     * 建议counts的记录数在1000以下,如果大过1000可以采取for循环里面查询子表的方案
     * @param counts 分组查询的记录集合
     * @param pageBean 分页对象
     * @return
     */
    public static RowBounds getGroupRowBounds(List<Integer> counts, PageBean pageBean){
        int offset = PageUtil.setParameter((int) counts.size(),pageBean);
        int pageSize = 0;
        for(int i = 1;i <= counts.size();i++){
            //每一条主记录对应的副表记录(多)
            int count = counts.get(i-1);
            pageSize = pageSize+count;
            if (offset == i){
                //设置起始值
                offset = pageSize;
            }
        }
        return new RowBounds(offset,pageSize);
    }

PageBean 是一个分页对象,网上类似代码很多,此处不贴出来
生成counts的参考sql写法

SELECT
          count(*)
        FROM (
          SELECT
            t.uuid
          FROM
            t_om_advice_feedback t
          LEFT JOIN t_om_feedback_module_relation r
          ON t.uuid = r.feedback_id and r.module_id <![CDATA[ <>  ]]> 0
          LEFT JOIN t_om_advice_feedback_module t2
          ON r.module_id = t2.uuid and r.module_id <![CDATA[ <>  ]]> 0
          LEFT JOIN t_om_advice_feedback_reply t3
          ON t.uuid = t3.feedback_id
          LEFT JOIN om_track_user u
          ON t3.reply_dd = u.dd
          LEFT JOIN t_om_advice_feedback_img t4
          ON t.uuid = t4.feedback_id
          WHERE t.feedback_dd = #{feedBackDd}
        )t
        group by t.uuid

其实就是对原来计算总数的count(*)的sql进行分组,得到一对多列表集合

主表主键一对多关联条数
13
24
35

二 就是不采用collection映射

查询语句改为只查询主表,然后在for循环中通过主表id将关联的副表数据查询出来。这种方法编程上比较麻烦,数据库查询次数较多,适合大量数据的时候。建议是在加上业务条件后的count(*)语句查询结果集在1000条以上时使用,因为对大数据量进行分组性能没有拆分多个小数据sql快,具体可以explain查看。
此处不张贴代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值