mybatis使用分页插件时,出现总页数统计不正确的情况

目录

场景描述

问题分析

解决方案


场景描述

今天前端突然告诉我,调用分页查询接口时,返回的总个数比实际的总个数小。

而在这个项目中,我使用的是mybatis plus自带的分页插件,其他接口都没有问题,偏偏这个接口出现了问题。

问题分析

定位到代码所在的sql(用了mybatis自带的查询构造器)

虽然关联了五张表,不是很优雅,但因为一个列表需要展示的东西太多,似乎也没有其他更好的办法。

抛开sql本身的不规范,我们分析一下为什么出现总个数不正确的情况。

控制台打印一下执行的sql:

统计个数的时候,执行了如下语句

==>  Preparing: SELECT COUNT(1) FROM tb_import_box tib WHERE (tib.deleted = 1 AND tib.status = ? AND tib.type = ?) 
==> Parameters: 1(Byte), 1(Byte)
<==    Columns: COUNT(1)
<==        Row: 4

而真正执行的查询sql如下

==>  Preparing: SELECT tib.*, tb.equip_num equipNum, tbs.box_spec_name boxSpecName, tc.categ_name categName, tp.pro_spec_no proSpecNo, tp.pro_spec_name proSpecName, tb.box_no boxNo, tt.task_no taskNo, tt.app_no appNo, tt.task_detail_type taskDetailType 
FROM tb_import_box tib
LEFT OUTER JOIN tb_task tt on tt.id = tib.task_id 
LEFT OUTER JOIN tb_box tb on tb.id = tib.box_id 
LEFT OUTER JOIN tb_box_spec tbs on tbs.box_spec_no = tb.box_spec_no 
LEFT OUTER JOIN tb_category tc on tb.categ_id = tc.id 
LEFT OUTER JOIN tb_pro_spec tp on tb.pro_spec_no = tp.pro_spec_no 
WHERE (tib.deleted = 1 AND tib.status = ? AND tib.type = ?) 
ORDER BY tib.status LIMIT ?,? 
==> Parameters: 1(Byte), 1(Byte), 0(Long), 30(Long)

再看结果,发现了完全相同的两行

解决方案

分页插件对sql做了优化,当sql使用的是左连接时,插件在统计总数量时,只会统一第一张表。

假设查询语句如下:

select * from a left join b on a.name = b.name;

如果b有两个相同的name与a对应,即a的name与b的name是一对多的关系时,会出现重复的查询结果。

这个时候 select count(*) from a left join b on a.name = b.name;  不等于 select count(*) from a; 了

查看数据库

确实有一张表出现了重复的数据,而这个字段在业务上也应该时不重复的,代码里已经做了校验了。估计是因为其他人直接通过数据库添加测试数据的,把这条重复的数据删掉即可。

—————————分割线——————————

再来谈谈分页插件,假设我们用的不是左连接,用的是内连接

计算总数时

因为内连接的条数不一定和第一张表相等,所以没有做什么优化处理,直接带入原sql计算。

其实就算是左外联,也不一定会完全省略后面的连接表

比如条件中出现了tp(也就是后面的关联表),这个时候插件就没办法忽略后面的关联表了,只能带入计算。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值