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

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

如上