PageHelper通过PageInfo获取total数据错误

2018-08-29  本文已影响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相关代码下次补上

上一篇下一篇

猜你喜欢

热点阅读