引出问题
项目中有用到左连接分页查询(一对多),但是分页插件统计的数据总数与数据库中查出的实际数据总数不符合,导致页面数据展示异常。
例:
select o.name,b.name from table_one AS o LEFT JOIN table_two AS t ...
假设 table_one
表中有6条数据,其中每条数据分别在 table_two
表中有两条对应的数据,那么上述SQL查询出一共有12条数据,在没有任何其他附加条件下,那么按理来说Mybatis-Plus的分页查询应该返回的数据总数Total应该等于12,但实际为6,为 table_one
的数据总数,这并不符合预期。
排查日志后发现
分页前统计数据总数的SQL只查询了
的数据条数:如下table_one
select count(*) from table_one
这显然是不对的。
解决办法
博主是通过关闭SQL优化器来实现的:
mapper.pageInfo(page, param)
熟悉的人都知道分页入参有个关键性参数:IPage
查看源码后发现:
default boolean optimizeCountSql() {
return true;
}
存在一个抽象方法optimizeCountSql,默认值为true,也就是开启sql优化
IPage有一个实现类Page,实现了此方法,并可以通过成员变量来设置其值
Page无参构造初始化了此值:
public Page() {
this.records = Collections.emptyList();
this.total = 0L;
this.size = 10L;
this.current = 1L;
this.orders = new ArrayList();
this.optimizeCountSql = true;
this.isSearchCount = true;
this.hitCount = false;
}
由此便可以声明一个分页入参:
Page<Object> page = new Page<>(current, size);
// 关闭sql优化
page.setOptimizeCountSql(false);
然后再次请求分页查询接口发现统计SQL由之前的单表变成了连表
select count(*) from table_one AS o LEFT JOIN table_two AS t