前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >得嘞,分页插件PageHelper返回记录总数total竟然出错了!

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

作者头像
京东技术
发布2024-03-07 10:38:08
2250
发布2024-03-07 10:38:08
举报
文章被收录于专栏:京东技术京东技术

导读

本文围绕分页插件PageHelper在使用过程中遇到的一个问题展开讨论。作者在运用PageHelper进行数据分页时,发现返回的记录总数total出现了错误。文章首先分析了可能出现该问题的原因,接着通过实际案例详细展示了问题复现的步骤。同时,文章也提供了针对这一问题的解决方案和优化建议。阅读本文将了解到分页插件PageHelper的使用技巧,以及在实际项目中如何快速定位并解决类似问题,提高代码质量和开发效率。这对于使用分页插件的开发者来说,具有一定的参考价值和启示作用。

01问题描述

在今年的敏捷团队建设中,我通过Suite执行器实现了一键自动化单元测试。Juint除了Suite执行器还有哪些执行器呢?由此我的Runner探索之旅开始了!

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

02问题分析

理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目标页面展示到屏幕。

1.sql错误导致返回信息有误?检查结果:经过数据执行日志中生成的sql,sql正常并且数据总条数也正确

2.PageHelper使用方式错误,导致数据错误检查结果:通过与项目中其他地方使用记录的对比,使用方式正确

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

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

PageInfo<T>构造方法

代码语言:javascript
复制
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构造方法

代码语言:javascript
复制
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结果更换了实例对象导致的

再次确认mapper返回结果,是Page的实例

03 、解决方案

理解,首先 MCube 会依据模板缓存状态判断是否需要网络获取最新模板,当获取到模板后进行模板加载,加载阶段会将产物转换为视图树的结构,转换完成后将通过表达式引擎解析表达式并取得正确的值,通过事件解析引擎解析用户自定义事件并完成事件的绑定,完成解析赋值以及事件绑定后进行视图的渲染,最终将目标页面展示到屏幕。 1.位图原理

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

更正的代码如下:

最佳实践

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-03-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 京东技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导读
  • 01 、问题描述
  • 02 、问题分析
  • 03 、解决方案
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档