Mybatis的插件 PageHelper 分页查询使用方法

时间:2021-11-11 22:38:34

Mybatis的一个插件,PageHelper,非常方便mybatis分页查询。国内牛人的一个开源项目,有兴趣的可以去看源码,都有中文注释(ps:某些源码一大堆英文,痛哭流涕!)

在github上仓库地址为:Mybatis-PageHelper

它支持基本主流与常用的数据库,这可以在它的文档上看到。这里记录一下使用的基本方法


0.查看文档与使用准备

开发文档有中文文档也有英文文档


PageHelper官方文档


============================================


Mybatis的插件 PageHelper 分页查询使用方法

====================================================================================


Mybatis的插件 PageHelper 分页查询使用方法


Mybatis的插件 PageHelper 分页查询使用方法

1.配置拦截器插件


这个是配置在mybatis-config.xml文件中

文档中的示例:

  1. <!--   
  2.     plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:  
  3.     properties?, settings?,   
  4.     typeAliases?, typeHandlers?,   
  5.     objectFactory?,objectWrapperFactory?,   
  6.     plugins?,   
  7.     environments?, databaseIdProvider?, mappers?  
  8. -->  
  9. <plugins>  
  10.     <!-- com.github.pagehelper为PageHelper类所在包名 -->  
  11.     <plugin interceptor="com.github.pagehelper.PageInterceptor">  
  12.         <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->  
  13.         <property name="param1" value="value1"/>  
  14.     </plugin>  
  15. </plugins>  

我的配置:

  1. <plugins>  
  2.     <plugin interceptor="com.github.pagehelper.PageInterceptor">  
  3.         <!-- config params as the following -->  
  4.         <!--<!–分页参数合理化  –>-->  
  5.         <property name="reasonable" value="true"/>  
  6.     </plugin>  
  7. </plugins>  

一些配置参数的说明可以参考文档: 【分页插件参数介绍】

这里就说明一下reasonable的配置:

reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页,pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。


那么如何选择这些配置参数,文档中也给出了详细说明:【如何选择配置这些参数】


2.在代码中使用

官方文档也有这部分说明和案例,那么我就以自己的使用案例

  1. @RequestMapping("/emps")  
  2. public String list(@RequestParam(required = false,defaultValue = "1",value = "pageNum")Integer pageNum,  
  3.                    Map<String,Object> map){  
  4.   
  5.     //引入分页查询,使用PageHelper分页功能  
  6.     //在查询之前传入当前页,然后多少记录  
  7.     PageHelper.startPage(pageNum,5);  
  8.     //startPage后紧跟的这个查询就是分页查询  
  9.     List<Employee> emps = employeeService.getAll();  
  10.     //使用PageInfo包装查询结果,只需要将pageInfo交给页面就可以  
  11.     PageInfo pageInfo = new PageInfo<>(emps,5);  
  12.     //pageINfo封装了分页的详细信息,也可以指定连续显示的页数  
  13.   
  14.     map.put("pageInfo",pageInfo);  
  15.     return "list";  
  16. }  

以上使用说明:

·在查询调用方法前声明分页信息(当前页,每页记录数)

·在查询调用方法对查询结果进行包装成PageInfo对象,也可以是定连续显示的页数,这也是常用功能。

注意:都是与查询方法紧挨着的,不要中间夹杂其它无关语句


之后把信息放在ModelAndView中就可以在前台访问了。


下面说一下为什么要把查询结果包装成PageInfo对象


3.PageInfo类说明


类源码(更多源码去github上查看即可):

  1. public class PageInfo<T> implements Serializable {  
  2.     private static final long serialVersionUID = 1L;  
  3.     //当前页  
  4.     private int pageNum;  
  5.     //每页的数量  
  6.     private int pageSize;  
  7.     //当前页的数量  
  8.     private int size;  
  9.   
  10.     //由于startRow和endRow不常用,这里说个具体的用法  
  11.     //可以在页面中"显示startRow到endRow 共size条数据"  
  12.   
  13.     //当前页面第一个元素在数据库中的行号  
  14.     private int startRow;  
  15.     //当前页面最后一个元素在数据库中的行号  
  16.     private int endRow;  
  17.     //总记录数  
  18.     private long total;  
  19.     //总页数  
  20.     private int pages;  
  21.     //结果集  
  22.     private List<T> list;  
  23.   
  24.     //前一页  
  25.     private int prePage;  
  26.     //下一页  
  27.     private int nextPage;  
  28.   
  29.     //是否为第一页  
  30.     private boolean isFirstPage = false;  
  31.     //是否为最后一页  
  32.     private boolean isLastPage = false;  
  33.     //是否有前一页  
  34.     private boolean hasPreviousPage = false;  
  35.     //是否有下一页  
  36.     private boolean hasNextPage = false;  
  37.     //导航页码数  
  38.     private int navigatePages;  
  39.     //所有导航页号  
  40.     private int[] navigatepageNums;  
  41.     //导航条上的第一页  
  42.     private int navigateFirstPage;  
  43.     //导航条上的最后一页  
  44.     private int navigateLastPage;  
  45.   
  46.     public PageInfo() {  
  47.     }  
  48.   
  49.     /** 
  50.      * 包装Page对象 
  51.      * 
  52.      * @param list 
  53.      */  
  54.     public PageInfo(List<T> list) {  
  55.         this(list, 8);  
  56.     }  
  57.   
  58.     /** 
  59.      * 包装Page对象 
  60.      * 
  61.      * @param list          page结果 
  62.      * @param navigatePages 页码数量 
  63.      */  
  64.     public PageInfo(List<T> list, int navigatePages) {  
  65.         if (list instanceof Page) {  
  66.             Page page = (Page) list;  
  67.             this.pageNum = page.getPageNum();  
  68.             this.pageSize = page.getPageSize();  
  69.   
  70.             this.pages = page.getPages();  
  71.             this.list = page;  
  72.             this.size = page.size();  
  73.             this.total = page.getTotal();  
  74.             //由于结果是>startRow的,所以实际的需要+1  
  75.             if (this.size == 0) {  
  76.                 this.startRow = 0;  
  77.                 this.endRow = 0;  
  78.             } else {  
  79.                 this.startRow = page.getStartRow() + 1;  
  80.                 //计算实际的endRow(最后一页的时候特殊)  
  81.                 this.endRow = this.startRow - 1 + this.size;  
  82.             }  
  83.         } else if (list instanceof Collection) {  
  84.             this.pageNum = 1;  
  85.             this.pageSize = list.size();  
  86.   
  87.             this.pages = this.pageSize > 0 ? 1 : 0;  
  88.             this.list = list;  
  89.             this.size = list.size();  
  90.             this.total = list.size();  
  91.             this.startRow = 0;  
  92.             this.endRow = list.size() > 0 ? list.size() - 1 : 0;  
  93.         }  
  94.         if (list instanceof Collection) {  
  95.             this.navigatePages = navigatePages;  
  96.             //计算导航页  
  97.             calcNavigatepageNums();  
  98.             //计算前后页,第一页,最后一页  
  99.             calcPage();  
  100.             //判断页面边界  
  101.             judgePageBoudary();  
  102.         }  
  103.     }  
  104.   
  105.   
  106. .......  
  107. }  

这里只列出所有属性和构造方法,那么可以清晰的看到一些属性的含义,一些属性是如何初始化,并且初始化值是怎样的,更多详细情况可以自己去查看源码,都有中文注释


那么可以很方便在页面进行值的获取输出


4.在页面获取值(实现分页)

  1. <!--通过bootstrap的栅格系统布局-->  
  2. <div class="container">  
  3.   
  4.     <!--标题-->  
  5.     <div class="row">  
  6.         <div class="col-md-12">  
  7.             <h1>SSM-CRUD</h1>  
  8.         </div>  
  9.   
  10.     </div>  
  11.   
  12.     <!--按钮-->  
  13.     <div class="row">  
  14.         <div class="col-md-4 col-md-offset-8">  
  15.             <button class="btn btn-primary">新增</button>  
  16.             <button class="btn btn-danger">删除</button>  
  17.         </div>  
  18.     </div>  
  19.   
  20.     <!--显示表格数据-->  
  21.     <div class="row">  
  22.         <div class="col-md-12">  
  23.             <table class="table table-hover">  
  24.                 <tr>  
  25.                     <th>#</th>  
  26.                     <th>empName</th>  
  27.                     <th>gender</th>  
  28.                     <th>email</th>  
  29.                     <th>deptName</th>  
  30.                     <th>操作</th>  
  31.                 </tr>  
  32.   
  33.   
  34.                 <c:forEach items="${pageInfo.list}" var="emp">  
  35.                     <tr>  
  36.                         <th>${emp.empId}</th>  
  37.                         <th>${emp.empName}</th>  
  38.                         <th>${emp.gender=="M"?"男":"女" }</th>  
  39.                         <th>${emp.email}</th>  
  40.                         <th>${emp.department.deptName}</th>  
  41.                         <th>  
  42.                             <button class="btn btn-primary">  
  43.                                 <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>  
  44.                                 编辑  
  45.                             </button>  
  46.   
  47.                             <button class="btn btn-danger">  
  48.                                 <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>  
  49.                                 删除  
  50.                             </button>  
  51.   
  52.                         </th>  
  53.                     </tr>  
  54.                 </c:forEach>  
  55.   
  56.             </table>  
  57.         </div>  
  58.   
  59.     </div>  
  60.   
  61.     <!--显示分页信息-->  
  62.     <div class="row">  
  63.         <!--文字信息-->  
  64.         <div class="col-md-6">  
  65.             当前第 ${pageInfo.pageNum} 页.总共 ${pageInfo.pages} 页.一共 ${pageInfo.total} 条记录  
  66.         </div>  
  67.   
  68.         <!--点击分页-->  
  69.         <div class="col-md-6">  
  70.             <nav aria-label="Page navigation">  
  71.                 <ul class="pagination">  
  72.                       
  73.                     <li><a href="${pageContext.request.contextPath}/emps?pn=1">首页</a></li>  
  74.                       
  75.                     <!--上一页-->  
  76.                     <li>  
  77.                         <c:if test="${pageInfo.hasPreviousPage}">  
  78.                             <a href="${pageContext.request.contextPath}/emps?pn=${pageInfo.pageNum-1}" aria-label="Previous">  
  79.                                 <span aria-hidden="true">«</span>  
  80.                             </a>  
  81.                         </c:if>  
  82.                     </li>  
  83.   
  84.                     <!--循环遍历连续显示的页面,若是当前页就高亮显示,并且没有链接-->  
  85.                     <c:forEach items="${pageInfo.navigatepageNums}" var="page_num">  
  86.                         <c:if test="${page_num == pageInfo.pageNum}">  
  87.                             <li class="active"><a href="#">${page_num}</a></li>  
  88.                         </c:if>  
  89.                         <c:if test="${page_num != pageInfo.pageNum}">  
  90.                             <li><a href="${pageContext.request.contextPath}/emps?pn=${page_num}">${page_num}</a></li>  
  91.                         </c:if>  
  92.                     </c:forEach>  
  93.   
  94.                     <!--下一页-->  
  95.                     <li>  
  96.                         <c:if test="${pageInfo.hasNextPage}">  
  97.                             <a href="${pageContext.request.contextPath}/emps?pn=${pageInfo.pageNum+1}"  
  98.                                aria-label="Next">  
  99.                                 <span aria-hidden="true">»</span>  
  100.                             </a>  
  101.                         </c:if>  
  102.                     </li>  
  103.                       
  104.                     <li><a href="${pageContext.request.contextPath}/emps?pn=${pageInfo.pages}">尾页</a></li>  
  105.                 </ul>  
  106.             </nav>  
  107.         </div>  
  108.   
  109.     </div>  
  110.   
  111.   
  112. </div>  

最后显示:

Mybatis的插件 PageHelper 分页查询使用方法


以上很常见的分页需求,可以非常方便的使用。
并且支持各种数据库,可以有多种方式进行引入插件,对于springBoot也有非常好的整合使用。

PageHelpe开源地址


github项目地址:https://github.com/pagehelper/Mybatis-PageHelper
码云 项目地址:http://git.oschina.net/free/Mybatis_PageHelper