mybatis-plus-join icon indicating copy to clipboard operation
mybatis-plus-join copied to clipboard

一对多的主子表场景selectJoinPage分页查询得到的实际数目与total不一致问题

Open Luyg88 opened this issue 1 year ago • 5 comments

当前使用版本(必填,否则不予处理)

1.4.12

该问题是如何引起的?(确定最新版也有问题再提!!!)

使用selectJoinPage分页查询,有leftjoin联表操作,生成查询总数目的sql却没有联表的leftjoin语句,这导致一对多的主子表查询时,查出来的数目和total对不上;比如主表10条数据,每条主表数据有2条子表数据(子表总共20条),这样主表leftjoin子表得到的数据有20条,但是selectJoinPage得到的total是10,这个问题应当怎么处理?有办法让生成的select count(*)也带上leftjoin联表查询吗 image

重现步骤(如果有就写完整)

报错信息

Luyg88 avatar Jun 08 '24 08:06 Luyg88

感觉分页一旦遇上了表连接问题很多,多对一的查询可以用,一对多不行, 比如demo中,user连接address查分页,按照user的 id 正序排, 此时虽然分页大小设置的10, 却只查到两个user, 因为其余的address 信息聚合到了 user的 list中去了

@Test
        void testJoin() {
                MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
                                .selectAll(UserDO.class)
                                .selectCollection(AddressDO.class, UserDTO::getAddressList)
                                .leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
                                .orderByAsc(UserDO::getId);

 
                Page<UserDTO> page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, wrapper);
              
        }

finalgene avatar Jun 14 '24 07:06 finalgene

看网上有说是因为id重复而触发了mybatis去重,需要设置伪列?不知道是不是这个问题. 但是我这也遇到该问题了,查到100条但是实际list只有2条,我想去增加伪列的时候,却不知道通过Lambda如何实现增加

1025946443 avatar Jun 28 '24 07:06 1025946443

@Luyg88 怎么解决了呢?

qq61966100 avatar Jul 26 '24 03:07 qq61966100

https://github.com/yulichang/mybatis-plus-join/issues/157

liuyuanting1209 avatar Aug 06 '24 10:08 liuyuanting1209

感觉分页一旦遇上了表连接问题很多,多对一的查询可以用,一对多不行, 比如demo中,user连接address查分页,按照user的 id 正序排, 此时虽然分页大小设置的10, 却只查到两个user, 因为其余的address 信息聚合到了 user的 list中去了

@Test
        void testJoin() {
                MPJLambdaWrapper<UserDO> wrapper = new MPJLambdaWrapper<UserDO>()
                                .selectAll(UserDO.class)
                                .selectCollection(AddressDO.class, UserDTO::getAddressList)
                                .leftJoin(AddressDO.class, AddressDO::getUserId, UserDO::getId)
                                .orderByAsc(UserDO::getId);

 
                Page<UserDTO> page = userMapper.selectJoinPage(new Page<>(1, 10), UserDTO.class, wrapper);
              
        }

本质是所谓的分页就是在sql后面拼接limit和offset,所以一对多的情况下,主表中的10条数据每条对应了n条关联表的数据,join后数据库sql执行完后就是有n*10条数据,你分页10条数据sql语句imit 10,把结果集的前10条数据封装到实体类中后,实际可能只拿了主表的5条数据与预期不符,所以可以走两边查询,第一遍只查询主表的主键用distinct去重查得到正确的条数和主表的主键,再关联查询一遍用刚刚分页查出来的·的主键列表过滤,得到结果集就是预期的分页结果集

wangjiancheng180 avatar Oct 11 '24 08:10 wangjiancheng180