关于 PageHelper 分页插件的使用以及其中的坑 您所在的位置:网站首页 pagehelper分页使用第二个sql分页 关于 PageHelper 分页插件的使用以及其中的坑

关于 PageHelper 分页插件的使用以及其中的坑

2023-07-05 02:00| 来源: 网络整理| 查看: 265

如何使用

直接导入依赖

 com.github.pagehelper  pagehelper-spring-boot-starter  1.2.13

常见的使用方式

public PageInfo findPage(int pageNum,int pageSize){      PageHelper.startPage(pageNum,pageSize);      List list=userDao.selectAll();      PageInfo pageInfo = new PageInfo(list);      return pageInfo; }

说明

startPage() 方法调用后必须紧跟 MyBatis 查询方法 startPage() 方法是静态方法, 只需要传入 pageNum 和 pageSize 两个参数 我们不需要对查询 SQL 做修改就可以达到分页的效果 PageInfo 里面包含了一整个页面的信息 PageInfo 构造函数传入的参数必须是 startPage() 后的那个方法得到的对象(原因下文解释) PageInfo 中的参数说明 public class PageInfo extends PageSerializable {    // 当前页的页码    private int pageNum;    // 页大小, 为分页时提供的参数    private int pageSize;    // 当前页的记录条数    private int size;    // 由第几条开始(数据库行号)    private int startRow;    // 第几条结束(数据库行号)    private int endRow;    // 一共有多少页    private int pages;    // 前一页的页号, 如果没有前一页就是为0    private int prePage;    // 后一页的页号, 如果没有前一页就是为0    private int nextPage;    // 是否是第一页    private boolean isFirstPage;    // 是否是最后一页    private boolean isLastPage;    // 是否有前一页    private boolean hasPreviousPage;    // 是否有后一页    private boolean hasNextPage;    // 每页显示的页码个数, 在构造方法里面被默认设置为8    private int navigatePages;    // 页码数    private int[] navigatepageNums;    // 首页    private int navigateFirstPage;    // 尾页    private int navigateLastPage;    // 方法省略 }

另外它还继承自 PageSerializable

public class PageSerializable implements Serializable {    private static final long serialVersionUID = 1L;    // 当前页的记录条数    protected long total;    // 当前页的每一条记录    protected List list;    // 方法省略 } PageHelper 使用中的坑 需求描述

出于安全性的考虑, 我想要查询到的 POJO 映射到 VO 类中,VO 类相比 POJO 类缺少了某些私密属性, 将 VO 作为基本元素封装到 PageInfo 中, 于是我写出来如下代码

PageInfo selectAll() {    // 开启分页 (PageNum,PageSize)    PageHelper.startPage(1, 2);    List posts = postMapper.selectAll();    // 属性拷贝    List postItemVOS = new ArrayList();    for (Post post : posts) {        PostItemVO postItemVO = new PostItemVO();        BeanUtils.copyProperties(post,postItemVO);        postItemVOS.add(postItemVO);   }    // PageInfo 封装    PageInfo pageInfo = new PageInfo(postItemVOS);    return pageInfo; }

Post 是我的 POJO, PostVO 是对应的 VO 类。数据库中查询得到 Post 集合,将其属性拷贝到 PostVO 集合。 乍一看其实写的不存在问题,但是我们在查询时就会出现问题 数据库表如下, 共有四条记录

得到的 PageInfo 如下

数据库中共有 4 条记录, 但是查询得到的 total 只有 2 条, 除此之外 nextPage,endRow…. 字段都出现了问题。

解决方法 方法一

先直接将查询结果封装到一个 PageInfo 中, 之后将将该 PageInfo 的 list 取出来做改造

PageInfo< selectAll() { PageHelper.startPage(1, 2); List posts = postMapper.selectAll(); // 直接将Post封装 PageInfo pageInfo = new PageInfo(posts); // 取出List进行数据转移 ArrayList postItemVOS = new ArrayList(); pageInfo.getList().forEach(post->{ PostItemVO postItemVO = new PostItemVO(); BeanUtils.copyProperties(post,postItemVO); postItemVOS.add(postItemVO); }); pageInfo.setList(postItemVOS); return pageInfo; }

查询结果如下

方法二 推荐

更加优雅的方式 , 我们对查询语句进行改造, 使其直接返回一个 VO 集合,也就是说数据库表直接映射到 VO 上, 之后直接将该 List 封装在 PageInfo 之后, 直接返回就行了.

1 需要对 PostMapper.xml  进行修改

          id, title, update_time, published, category_id select from post order by update_time desc

2 在 PostMapper 接口中添加相关方法

List selectAllItem();

3 编写测试

PageInfo selectAllItem() { PageHelper.startPage(1, 2); List posts = postMapper.selectAllItem(); PageInfo pageInfo = new PageInfo(posts); return pageInfo; }

如果你有更好的解决方法欢迎留言评论。

原因分析

total 字段为例, 为什么正确的查询结果是 4, 但是用之前的错误查询方法的结果是 2。 先分析之前的错误查询方法的代码。 打个断点,我们发现,在 startPage() 调用之后, 随后的一个查询被进行了分页, 查询结果被封装为了一个 Page 对象:

查看 com.github.pagehelper.Page 源代码, Page 对象中包含了之后被封装到 PageInfo 中的信息:

也就是说, 我们的查询结果就已经包含了 PageInfo 之后需要的信息。查询得到的是一个 Page 实例,而不仅仅是一个 List, 所以说, 只对 posts进行 POJO 的拷贝是不够的, 这会丢失我们的分页信息。

对正确的查询过程进行调试分析:

1 被分页之后得到一个 Page 对象:

2 调用 PageInfo 构造函数会执行一个方法判断传入的参数是否为 Page 对象:

假如是之前的那种错误方法, 我们传入的是 List 对象, 那么 this.total就被初始化为了 List 的长度。 这就解释了为什么错误的方法得到的分页对象的 total 为 2

参考资料

如何使用分页插件

PageHelper,从pageinfo 中取到的total不正确的处理。(史上最最最最最最详细l!!!)20fen的博客-CSDN博客pagehelper total不对



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有