写点什么

得嘞,分页插件 PageHelper 返回记录总数 total 竟然出错了!

  • 2024-03-20
    北京
  • 本文字数:1588 字

    阅读完需:约 5 分钟

问题描述

分页返回的记录总数 total 和每页数量 pageSize 一致,数据库统计的数量大于当前返回的总记录数 total,以下是相关代码


问题分析

  1. sql 错误导致返回信息有误?

  2. 检查结果:经过数据执行日志中生成的 sql,sql 正常并且数据总条数也正确

  3. PageHelper 使用方式错误,导致数据错误

  4. 检查结果:通过与项目中其他地方使用记录的对比,使用方式正确

  5. 返回结果后有中间处理导致总数减少

  6. 检查结果:网上有人遇到 对返回结果有类型转化导致total错误的情况, 以此类推,发现当前代码虽没有对返回结果进行类型转换但是对 mapper 返回的结果更换了实例对象然后将更换后的对象包装,

  7. 进一步查看包装成PageInfo<T>时源码并没有关于 total 参数的处理,

  8. PageInfo<T>构造方法


    public class PageInfo<T> extends PageSerializable<T> {    /**     * 包装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(); } } }
复制代码


继续查看父类PageSerializable,发现有关于total参数的处理,即mapper返回的list不是Page的实例时total会被设置为返回list的size大小
**PageSerializable构造方法**
复制代码


    public PageSerializable(List<T> list) {        this.list = list;        if(list instanceof Page){            this.total = ((Page)list).getTotal();        } else {            this.total = list.size();        }    }
复制代码


进一步debug,发现返回list确实不是Page类的实例,故推断出这一结果是由于对mapper返回list结果更换了实例对象导致的,  ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5f7e08bd94d2456a93001a1ef59ab277~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=1926&h=950&s=197752&e=png&b=3c3f41)  再次确认mapper返回结果,是Page的实例  ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/d3718d4149674e4f832c1bd16bfa45ef~tplv-k3u1fbpfcp-jj-mark:0:0:0:0:q75.image#?w=2680&h=1770&s=430641&e=png&b=2b2b2b)
复制代码

解决方案

使用 mapper 返回的对象直接构造 PageInfo 对象,并在此基础上获取分页信息


更正的代码如下:


最佳实践

在使用 PageInfo<T> pageInfo = new PageInfo<>(T)构造 PageInfo 时直接使用 mapper 返回对象,不要进行类型转换或转存等操作,以免丢失数据。

发布于: 刚刚阅读数: 4
用户头像

拥抱技术,与开发者携手创造未来! 2018-11-20 加入

我们将持续为人工智能、大数据、云计算、物联网等相关领域的开发者,提供技术干货、行业技术内容、技术落地实践等文章内容。京东云开发者社区官方网站【https://developer.jdcloud.com/】,欢迎大家来玩

评论

发布
暂无评论
得嘞,分页插件PageHelper返回记录总数total竟然出错了!_京东科技开发者_InfoQ写作社区