pagehelper分页查询明明下一页没有数据了却还是返回了数据

简介: pagehelper分页查询明明下一页没有数据了却还是返回了数据

场景复现


数据库初始化有9条记录。当我通过分页插件去查询数据库时,查询第2页,每页10条记录时,查询的结果竟然有9条数据。结果显然不合理,因为我查询第2页,按照逻辑应该查询第11-20条记录,因此不存在,所以返回为空,但是现在却返回9条记录。


疑问如下:


  • 为什么返回数据???
  • 为什么返回9条数据???


解决办法


pagehelper:
#  helperDialect: mysql
  reasonable: false   # 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据


源码分析


源码跟踪


直接定位到PageInterceptor的intercept方法(为什么直接定位到这?)


@Override
    public Object intercept(Invocation invocation) throws Throwable {
        try {
            //省略内容,省略内容,省略内容
            List resultList;
            //步骤1:调用方法判断是否需要进行分页,如果不需要,直接返回结果
            if (!dialect.skip(ms, parameter, rowBounds)) {
                //判断是否需要进行 count 查询
                if (dialect.beforeCount(ms, parameter, rowBounds)) {
                    //步骤2:查询总条数
                    Long count = count(executor, ms, parameter, rowBounds, resultHandler, boundSql);
                    //处理查询总数,返回 true 时继续分页查询,false 时直接返回
                    //步骤3:保存总条数
                    if (!dialect.afterCount(count, parameter, rowBounds)) {
                        //当查询总数为 0 时,直接返回空的结果
                        return dialect.afterPage(new ArrayList(), parameter, rowBounds);
                    }
                }
               //步骤4:执行分页查询
                resultList = ExecutorUtil.pageQuery(dialect, executor,
                        ms, parameter, rowBounds, resultHandler, boundSql, cacheKey);
            } else {
                //rowBounds用参数值,不使用分页插件处理时,仍然支持默认的内存分页
                resultList = executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);
            }
            //步骤5:封装结果
            return dialect.afterPage(resultList, parameter, rowBounds);
        } finally {
            if(dialect != null){
                dialect.afterAll();
            }
        }
    }


我们看步骤3,保存总条数,总条数会保存到ThreadLocal的Page对象中,如图代码所示


//AbstractHelperDialect的afterCount方法
public boolean afterCount(long count, Object parameterObject, RowBounds rowBounds) {
        Page page = getLocalPage();
        //(重点,重点,重点)把count保存到page对象中
        page.setTotal(count);
        if (rowBounds instanceof PageRowBounds) {
            ((PageRowBounds) rowBounds).setTotal(count);
        }
        //pageSize < 0 的时候,不执行分页查询
        //pageSize = 0 的时候,还需要执行后续查询,但是不会分页
        if (page.getPageSize() < 0) {
            return false;
        }
        return count > ((page.getPageNum() - 1) * page.getPageSize());
    }


重点来了,我们跟进Page的setTotal方法


//Page###setTotal
public void setTotal(long total) {
        this.total = total;
        if (total == -1) {
            pages = 1;
            return;
        }
        if (pageSize > 0) {
            pages = (int) (total / pageSize + ((total % pageSize == 0) ? 0 : 1));
        } else {
            pages = 0;
        }
        //分页合理化,针对不合理的页码自动处理
        if ((reasonable != null && reasonable) && pageNum > pages) {
            if(pages!=0){
                //把pageNum设置为最后一页,震惊
                //把pageNum设置为最后一页,震惊
                //把pageNum设置为最后一页,震惊
                pageNum = pages;
            }
            calculateStartAndEndRow();
        }
    }


问题解析


为什么返回数据???


因为我查询的页数(pageNum = 2)大于总页数(pages = 1),因此把pages赋值给pageNum,查询最后一页肯定有数据===!


为什么返回9条数据???


因为我查询的页数(pageNum = 2)大于总页数(pages = 1),因此把pages赋值给pageNum,查询最后一页根据分析就是9条===!


目录
相关文章
|
4月前
PageHelper分页插件拼接动态排序语句
PageHelper分页插件拼接动态排序语句
100 0
|
29天前
uniapp 返回上一页
uniapp 返回上一页
|
9月前
uniapp返回上一页
uniapp返回上一页
81 0
|
7月前
|
前端开发
使用PageHelper插件获取数据总条数不对的问题的解决方案
使用PageHelper插件获取数据总条数不对的问题的解决方案
73 0
|
11月前
|
前端开发 Java 数据库
pagination分页插件的getResult明明有数据,但是getTotal方法为0
pagination分页插件的getResult明明有数据,但是getTotal方法为0
172 0
使用PrinterJob进行分页打印
使用PrinterJob进行分页打印
113 0
|
SQL 前端开发
stream排序导致pageHelper分页失效处理
现有一查询会员上课记录的需求,要求按照上课时间进行倒序排列,考虑到后期数据量很多,使用逻辑层进行排序,但是前端小姐姐反应说查询的总记录数不正确.测试库中每页查询20条,实际所有数据总共37条,但是返回的总记录数竟然是20条,说明pageHelper分页失效.
stream排序导致pageHelper分页失效处理
分页获取数据列表GetListByPage
分页获取数据列表GetListByPage
66 0
|
前端开发
分页重复问题思考
目前项目中存在一个问题,列表会出现数据重复! 原因很容易想到,由于排序原因新添加数据会排在顶部。 勤劳的我们又要开始摸头了 :-)
196 0