欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用PageInfo做分页时手动设置参数的实现方式

程序员文章站 2022-06-04 11:00:11
...

使用PageInfo做分页时手动设置参数的实现方式

转载请标明出处:
原文首发于:http://www.zhangruibin.com
本文出自RebornChang的博客

在做项目开发的时候,pagehelper是我们经常使用的一个分页插件,源码地址:com.github.pagehelper。
针对com.github.pagehelper的基本使用方法及介绍在这片博文中就不进行介绍了,不知道pagehelper是什么或者不清楚怎么用的朋友请自行百度,这里不再赘述。
博主写技术文章一般喜欢嵌套在现实的生产开发中进行介绍,本次的介绍也依然是博主在进行项目开发的时候遇到的问题,因为走了写弯路,所以写出来以供参考。

需求背景

在一个项目中我们有很多需要调用外部接口,所以客户想要一个对这些接口的调用情况统计,比如说接口A,调用了多少次,每次成功还是失败,携带的参数以及返回的参数是什么,请求的响应时间是多少。基于这个需求引出了下面的这个问题:统计的时候,对统计结果怎样分页。

统计结果进行分页

如果直接使用pagehelper进行分页的话,就直接限制到了数据库执行sql的分页,这样就不能保证数据的完整性,因为我要在页面上展示的20条数据,可能是由几万条数据进行分类整理统计出来的20条信息,那就不能用pagehelper进行自动分页了,这时候就需要手动分页。

手动分页所需的类PageInfo里面各参数含义

//当前页
 private int pageNum;
 //每页的数量
 private int pageSize;
 //当前页的数量
 private int size;
 //当前页展示的数据的起始行
 private int startRow;
 //当前页展示的数据的结束行
 private int endRow;
 //总记录数--所需要进行分页的数据条数
 private long total;
 //总页数
 private int pages;
 //页面展示的结果集,比如说当前页要展示20条数据,则此list为这20条数据
 private List<T> list;
 //前一页页码
 private int prePage;
 //下一页页码
 private int nextPage;
 //是否为第一页,默认为false,是第一页则设置为true
 private boolean isFirstPage ;
 //是否为最后一页默认为false,是最后一页则设置为true
 private boolean isLastPage ;
 //是否有前一页,默认为false,有前一页则设置为true
 private boolean hasPreviousPage ;
 //是否有下一页,默认为false,有后一页则设置为true
 private boolean hasNextPage ;
 //导航页码数,所谓导航页码数,就是在页面进行展示的那些1.2.3.4...
 //比如一共有分为两页数据的话,则将此值设置为2
 private int navigatePages;
 //所有导航页号,一共有两页的话则为[1,2]
 private int[] navigatepageNums;
 //导航条上的第一页页码值
 private int navigateFirstPage;
 //导航条上的最后一页页码值
 private int navigateLastPage;

手动设置PageInfo的各参数,指定分页规则

注:此处不提供前台的页码传参之类的代码,有需要的话可以百度,一堆。
前台传过来的一个对象pagebale,对象有两个参数。1:页码。2:每页的数据条数。

自动分页

如果是传统简单的分页,则直接使用默认的Pageable进行分页就行了:

PageHelper.startPage(pageable.getPageNumber(), pageable.getPageSize());

//在这里执行要进行分页的sql,获取分页后的结果集resultList

return new PageInfo<Object>(resultList);

手动分页

看了上面的自动分页代码之后,是不是有一种恍然大悟的感觉,所谓手动分页,只需要把这个return new PageInfo(resultList);的PageInfo这个对象的参数手动定义下就行了。
类似早期的物理分页,只不过是自己计算边界值之类的东西,具体的设置方法如下:

      //2019-03-04 zhrb 手动封装PageInfo参数进行分页
      PageInfo realPageInfo = new PageInfo<InterfaceMonitorLogCountVo>(interfaceMonitorLogCountVoList);
      int start = 0;
      int end = 0;
      int totalPages = 0;
      int totalRecord = 0;
      int pageSize = 0;
      int size  = 0;
      int number = 0;
      size  = pageable.getPageSize();
      number = pageable.getPageNumber();
      pageSize = pageable.getPageSize();
      totalRecord = interfaceMonitorLogCountVoList.size();
      //设置总数
      realPageInfo.setTotal(totalRecord);
      //设置每页的显示条数
      realPageInfo.setPageSize(size);
      //设置要显示的是第几页的数据
      realPageInfo.setPageNum(number);
      realPageInfo.setSize(totalRecord);
      //计算获取对应的要显示的数据
      if(totalRecord%pageSize==0){
          totalPages = totalRecord / pageSize;
      }else {
          totalPages = totalRecord / pageSize + 1;
      }
      realPageInfo.setPages(totalPages);
      //初始边界值计算
      if (number == 1){
          start = 0;
          realPageInfo.setHasPreviousPage(false);
          realPageInfo.setPrePage(0);
          realPageInfo.setIsFirstPage(true);
      }else {
          start = realPageInfo.getPageSize()*(realPageInfo.getPageNum()-1);
          realPageInfo.setHasPreviousPage(true);
          realPageInfo.setPrePage(number-1);
          realPageInfo.setIsFirstPage(false);
      }
      realPageInfo.setStartRow((number-1)*pageSize);
      //结束边界值计算
      if ((start+realPageInfo.getPageSize() > realPageInfo.getTotal())){
          end = totalRecord;
          realPageInfo.setHasNextPage(false);
          realPageInfo.setIsLastPage(true);
          realPageInfo.setEndRow(totalRecord);
      }else {
          end = start + realPageInfo.getPageSize();
          realPageInfo.setHasNextPage(true);
          realPageInfo.setNextPage(number + 1);
          realPageInfo.setIsLastPage(false);
          realPageInfo.setEndRow((number)*pageSize);
      }
      if (start < end && end <= totalRecord){
          realPageInfo.setList(interfaceMonitorLogCountVoList.subList(start,end));
      }
      if(realPageInfo.getSize() == 0) {
          realPageInfo.setStartRow(0);
          realPageInfo.setEndRow(0);
      } else {
          realPageInfo.setStartRow(realPageInfo.getStartRow() + 1);
          realPageInfo.setEndRow(realPageInfo.getStartRow()-1+realPageInfo.getSize());
      }
      realPageInfo.setPages(totalPages);
      realPageInfo.setNavigateLastPage(totalPages>number?number+1:totalPages);
      return realPageInfo;

然后在controller层将返回的结果放入ModelMap中就行了:


modelMap.addAttribute("page",realPageInfo ); 

此外,本博文提供一个封装好的PageBean,内容摘自网络,有想法手动写分页的博友可以参考,如有侵权请留言博主,博主将对响应内容进行删除:

package com.oms.util;
import org.apache.poi.ss.formula.functions.T;

import java.util.List;
/**
* @ClassName PageBean
* @Description TODO 手动分页基础类
* @Date 2019/3/4 9:12
* @Version
*/
public class PageBean<T> {
  //已知的参数
  //当前页,从请求那边传过来
  private int pageNum;
  //每页显示的数据条数
  private int pageSize;
  //总的记录条数。查询数据库得到的数据
  private int totalRecord;

  //需要计算得来
  //总页数,通过totalRecord和pageSize计算可以得来
  private int totalPage;
  //开始索引,也就是我们在数据库中要从第几行数据开始拿,有了startIndex和pageSize,
  //就知道了limit语句的两个数据,就能获得每页需要显示的数据了
  private int startIndex;
  //将每页要显示的数据放在list集合中
  private List<T> list;
  //分页显示的页数,比如在页面上显示1,2,3,4,5页,start就为1,end就为5,这个也是算过来的
  private int start;
  private int end;
  //通过pageNum,pageSize,totalRecord计算得来tatalPage和startIndex
  //构造方法中将pageNum,pageSize,totalRecord获得
  public PageBean(int pageNum,int pageSize,int totalRecord) {
      this.pageNum = pageNum;
      this.pageSize = pageSize;
      this.totalRecord = totalRecord;

      //totalPage 总页数
      if(totalRecord%pageSize==0){
          //说明整除,正好每页显示pageSize条数据,没有多余一页要显示少于pageSize条数据的
          this.totalPage = totalRecord / pageSize;
      }else{
          //不整除,就要在加一页,来显示多余的数据。
          this.totalPage = totalRecord / pageSize +1;
      }
      //开始索引
      this.startIndex = (pageNum-1)*pageSize ;
      //显示5页,这里自己可以设置,想显示几页就自己通过下面算法修改
      this.start = 1;
      this.end = 5;
      //显示页数的算法

      if(totalPage <=5){
          //总页数都小于5,那么end就为总页数的值了。
          this.end = this.totalPage;
      }else{
          //总页数大于5,那么就要根据当前是第几页,来判断start和end为多少了,
          this.start = pageNum - 2;
          this.end = pageNum + 2;

          if(start < 0){
              //比如当前页是第1页,或者第2页,那么就不如和这个规则,
              this.start = 1;
              this.end = 5;
          }
          if(end > this.totalPage){
              //比如当前页是倒数第2页或者最后一页,也同样不符合上面这个规则
              this.end = totalPage;
              this.start = end - 5;
          }
      }
  }
  //get、set方法。
  public int getPageNum() {
      return pageNum;
  }

  public void setPageNum(int pageNum) {
      this.pageNum = pageNum;
  }

  public int getPageSize() {
      return pageSize;
  }

  public void setPageSize(int pageSize) {
      this.pageSize = pageSize;
  }

  public int getTotalRecord() {
      return totalRecord;
  }

  public void setTotalRecord(int totalRecord) {
      this.totalRecord = totalRecord;
  }

  public int getTotalPage() {
      return totalPage;
  }

  public void setTotalPage(int totalPage) {
      this.totalPage = totalPage;
  }

  public int getStartIndex() {
      return startIndex;
  }

  public void setStartIndex(int startIndex) {
      this.startIndex = startIndex;
  }

  public List<T> getList() {
      return list;
  }

  public void setList(List<T> list) {
      this.list = list;
  }

  public int getStart() {
      return start;
  }

  public void setStart(int start) {
      this.start = start;
  }

  public int getEnd() {
      return end;
  }

  public void setEnd(int end) {
      this.end = end;
  }
}

Over!