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

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

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

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

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

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

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();

    1 this.pages = page.getPages(); 2 this.size = page.size(); 3 //由于结果是>startRow的,所以实际的需要+1 4 if (this.size == 0) { 5 this.startRow = 0; 6 this.endRow = 0; 7 } else { 8 this.startRow = page.getStartRow() + 1; 9 //计算实际的endRow(最后一页的时候特殊) 10 this.endRow = this.startRow - 1 + this.size; 11 }

    } else if (list instanceof Collection) { this.pageNum = 1; this.pageSize = list.size();

    1 this.pages = this.pageSize > 0 ? 1 : 0; 2 this.size = list.size(); 3 this.startRow = 0; 4 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结果更换了实例对象导致的,

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

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

更正的代码如下:

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

点赞
收藏

评论区

加载中...

相关推荐

sql的left join 、right join 、inner join之间的区别

sql的leftjoin、rightjoin、innerjoin之间的区别  leftjoin(左联接)返回包括左表中的所有记录和右表中联结字段相等的记录   rightjoin(右联接)返回包括右表中的所有记录和左表中联结字段相等的记录  innerjoin(等值连接)只返回两个表中联结字段相等的行举例如下: 

MySQL日志体系详解

前言日志是MySQL数据库的重要组成部分。日志文件中记录着MySQL数据库运行期间发生的变化;也就是说用来记录MySQL数据库的客户端连接状况、SQL语句的执行情况和错误信息等。当数据库遭到意外的损坏时,可以通过日志查看文件出错的原因,并且可以通过日志文件进行数据恢复。MySQL的日志体系有如下几种分类:1.错误日志2.查询日志

Spotlight on MySQL 参数详解

!(https://oscimg.oschina.net/oscnet/1eb23b1eb1612a58b59cdd6d0e2927e38cc.png) 1、Sessios会话TotalUsers:总用户数前连接到MySQL服务器的用户会话总数ActiveUsers:活跃用户此控件表示连接到当前正在执行SQL语句或其他数据库

Prometheus监控学习笔记之PromQL简单示例

0x00简单的时间序列选择返回度量指标http_requests_total的所有时间序列样本数据:http_requests_total返回度量指标名称为http_requests_total,标签分别是job"apiserver",handler"/api/comments"

mysql分页(ajax)

分页有多种方式,mysql的limit是个不错的选择,通过ajax实现异步刷新,将当前页数和每页数量传入后台即可1\.首先后台要拿到总记录数和所需显示数据列表,所以要分别写两个sql方法我这里是通过spring的注解方式写的sql,其它方法原理是一样的!复制代码(https://static.oschina.net/uploads/

PageImpl在springboot中的JSON序列化问题

在restapi中使用 org.springframework.data.domain.PageImpl 返回分页数据,有出现一些问题,问题以及解决方式如下:_(1) 返回的结果在springboot1.x 和springboot2.x中不一致_例如以下API@RestControllerpublicclas