美文网首页
PageHelper通过PageInfo获取total数据错误

PageHelper通过PageInfo获取total数据错误

作者: 朝五晚九浪迹天涯 | 来源:发表于2018-08-29 01:17 被阅读0次

    说明

    项目环境基于SpringBoot2.x + Mybatis3 + PageHelper5.x, 其他环境下是否有效未经检测.

    使用Maven引入依赖, 在此只贴出PageHelper的依赖, 其他请自行配置.

    PageHelper的依赖

    <dependency>
                <groupId> com.github.pagehelper</groupId>
                <artifactId>pagehelper-spring-boot-starter</artifactId>
                <version>1.2.5</version>
    </dependency>
    

    Note

    如果你使用xml配置mybatis, 网上可能有介绍加入如下配置

    <!-- 配置mybatis的分页插件PageHelper -->
    <plugins>
                <!-- com.github.pagehelper为PageHelper类所在包名 -->
                <plugin interceptor="com.github.pagehelper.PageInterceptor">
                </plugin>
    </plugins>
    
    该配置在PageHelper5.x中会报错, 直接删除即可.

    引言

    项目中使用PageHelper进行分页查询, 结果集中携带total动态生成分页标签. 常规做法, 通过mapper获取结果集List初始化PageInfo, 再调用getTotal方法得到总数.

    核心语句

    //pageNum和pageSize自行获取
    PageHelper.startPage(pageNum, pageSize);
    List<User> users= userService.getUsers();
    PageInfo info = new PageInfo(list);
    int total = info.getTotal();
    
    在真正使用时, 会发现total的值并不等于数据库中记录总数, 并且该值永远等于查询页的记录数, 即getTotal和getSize()效果相同. 读者若自行查看SQL日志, 可发现startPage()方法成功执行, 返回的List是符合查询条件的.

    解决方法

    在PageHelper的官方Github中, 有类似Issues, 但已关闭.

    变更语句

    Page page = PageHelper.startPage(pageNum, pageSize);
    //使用page的getTotal()
    int total = page.getTotal();
    

    问题分析

    Issues中有老哥认为通过PageInfo得到total的途径是没毛病的, 但问题确实发生了, 而且此方法能解决燃眉之急, 那我就来啃啃源码探探究竟 :)

    从PageInfo看起

    /**
         * 包装Page对象
         *
         * @param list
         */
        public PageInfo(List<T> list) {
            this(list, 8);
        }
    
        /**
         * 包装Page对象
         *
         * @param list          page结果
         * @param navigatePages 页码数量
         */
        public PageInfo(List<T> list, int navigatePages) {
            super(list);
            if (list instanceof Page) {
                Page page = (Page) list;
                this.pageNum = page.getPageNum();
                this.pageSize = page.getPageSize();
    
                this.pages = page.getPages();
                this.size = page.size();
                //由于结果是>startRow的,所以实际的需要+1
                if (this.size == 0) {
                    this.startRow = 0;
                    this.endRow = 0;
                } else {
                    this.startRow = page.getStartRow() + 1;
                    //计算实际的endRow(最后一页的时候特殊)
                    this.endRow = this.startRow - 1 + this.size;
                }
            } else if (list instanceof Collection) {
                this.pageNum = 1;
                this.pageSize = list.size();
    
                this.pages = this.pageSize > 0 ? 1 : 0;
                this.size = list.size();
                this.startRow = 0;
                this.endRow = list.size() > 0 ? list.size() - 1 : 0;
            }
            if (list instanceof Collection) {
                this.navigatePages = navigatePages;
                //计算导航页
                calcNavigatepageNums();
                //计算前后页,第一页,最后一页
                calcPage();
                //判断页面边界
                judgePageBoudary();
            }
        }
    
    这部分不涉及total, 直接点开super()
    public PageSerializable(List<T> list) {
            this.list = list;
            if(list instanceof Page){
                this.total = ((Page)list).getTotal();
            } else {
                this.total = list.size();
            }
        }
    
    从源码看出, 如果用结果集的List初始化PageInfo, total与size相等, 那么total与预期不符是自然而然的.

    Page相关代码下次补上

    相关文章

      网友评论

          本文标题:PageHelper通过PageInfo获取total数据错误

          本文链接:https://www.haomeiwen.com/subject/iypcwftx.html