当前使用版本(必填,否则不予处理)
v3.4.3.3
该问题是如何引起的?(确定最新版也有问题再提!!!)
maxLimit启用后,size参数大于maxLimit,查询第二页时可能出现records数据不对,size属性没有自动调整为maxLimit值
重现步骤(如果有就写完整)
示例:
1. 全局maxLimit 配置为 10
2. 数据库数据总数为 20
3. 分页查询参数:{"current": 2, "searchTotal": true, "size": 500}
4. 返回数据:
{
"current": 2,
"size": 500,
"searchTotal": true,
"total": 20,
"records": [],
"totalPage": 1
}
注:返回的
size属性没有重置为 10(maxLimit),records为空数组。期望size调整为10后再返回第二页数据
源码定位:
public class PaginationInnerInterceptor implements InnerInterceptor {
/**
* 这里进行count,如果count为0这返回false(就是不再执行sql了)
*/
@Override
public boolean willDoQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
if (page == null || page.getSize() < 0 || !page.searchCount()) {
return true;
}
......
page.setTotal(total);
// 重点方法 current > pages (2 > 1)
return continuePage(page);
}
@Override
public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
......
// size 小于 0 且不限制返回值则不构造分页sql
Long _limit = page.maxLimit() != null ? page.maxLimit() : maxLimit;
......
handlerLimit(page, _limit);
......
}
/**
* count 查询之后,是否继续执行分页
*
* @param page 分页对象
* @return 是否
*/
protected boolean continuePage(IPage<?> page) {
if (page.getTotal() <= 0) {
return false;
}
// current > pages
// 2 > 1
if (page.getCurrent() > page.getPages()) {
if (overflow) {
//溢出总页数处理
handlerOverflow(page);
} else {
// 超过最大范围,未设置溢出逻辑中断 list 执行
return false;
}
}
return true;
}
/**
* 处理超出分页条数限制,默认归为限制数
*
* @param page IPage
*/
protected void handlerLimit(IPage<?> page, Long limit) {
final long size = page.getSize();
if (limit != null && limit > 0 && (size > limit || size < 0)) {
page.setSize(limit);
}
}
}
if (!query.willDoQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql)) {
// 返回空集合
return Collections.emptyList();
}
query.beforeQuery(executor, ms, parameter, rowBounds, resultHandler, boundSql);
注:
handlerLimit逻辑应该执行时机应提前
报错信息
Comment From: lan-dian
你好,我在最新的版本中,分析了一下源码,已经修复了相关问题
protected void handlerLimit(IPage<?> page) {
final long size = page.getSize();
Long pageMaxLimit = page.maxLimit();
Long limit = pageMaxLimit != null ? pageMaxLimit : maxLimit;
if (limit != null && limit > 0 && size > limit) {
page.setSize(limit);
}
}
Comment From: miemieYaho
如上