Mybatis的一个插件,PageHelper,非常方便mybatis分页查询。国内牛人的一个开源项目,有兴趣的可以去看源码,都有中文注释(ps:某些源码一大堆英文,痛哭流涕!)
在github上仓库地址为:Mybatis-PageHelper
它支持基本主流与常用的数据库,这可以在它的文档上看到。这里记录一下使用的基本方法
开发文档有中文文档也有英文文档
============================================
====================================================================================
这个是配置在mybatis-config.xml文件中
文档中的示例:
- <!--
- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
- properties?, settings?,
- typeAliases?, typeHandlers?,
- objectFactory?,objectWrapperFactory?,
- plugins?,
- environments?, databaseIdProvider?, mappers?
- -->
- <plugins>
- <!-- com.github.pagehelper为PageHelper类所在包名 -->
- <plugin interceptor="com.github.pagehelper.PageInterceptor">
- <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
- <property name="param1" value="value1"/>
- </plugin>
- </plugins>
<!-- plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下: properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,objectWrapperFactory?, plugins?, environments?, databaseIdProvider?, mappers? --> <plugins> <!-- com.github.pagehelper为PageHelper类所在包名 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 --> <property name="param1" value="value1"/> </plugin> </plugins>
我的配置:
- <plugins>
- <plugin interceptor="com.github.pagehelper.PageInterceptor">
- <!-- config params as the following -->
- <!--<!–分页参数合理化 –>-->
- <property name="reasonable" value="true"/>
- </plugin>
- </plugins>
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <!-- config params as the following --> <!--<!–分页参数合理化 –>--> <property name="reasonable" value="true"/> </plugin> </plugins>
一些配置参数的说明可以参考文档: 【分页插件参数介绍】
这里就说明一下reasonable的配置:
reasonable
:分页合理化参数,默认值为false
。当该参数设置为 true
时,pageNum<=0
时会查询第一页,pageNum>pages
(超过总数时),会查询最后一页。默认false
时,直接根据参数进行查询。
那么如何选择这些配置参数,文档中也给出了详细说明:【如何选择配置这些参数】
官方文档也有这部分说明和案例,那么我就以自己的使用案例
- @RequestMapping("/emps")
- public String list(@RequestParam(required = false,defaultValue = "1",value = "pageNum")Integer pageNum,
- Map<String,Object> map){
- //引入分页查询,使用PageHelper分页功能
- //在查询之前传入当前页,然后多少记录
- PageHelper.startPage(pageNum,5);
- //startPage后紧跟的这个查询就是分页查询
- List<Employee> emps = employeeService.getAll();
- //使用PageInfo包装查询结果,只需要将pageInfo交给页面就可以
- PageInfo pageInfo = new PageInfo<>(emps,5);
- //pageINfo封装了分页的详细信息,也可以指定连续显示的页数
- map.put("pageInfo",pageInfo);
- return "list";
- }
@RequestMapping("/emps") public String list(@RequestParam(required = false,defaultValue = "1",value = "pageNum")Integer pageNum, Map<String,Object> map){//引入分页查询,使用PageHelper分页功能 //在查询之前传入当前页,然后多少记录 PageHelper.startPage(pageNum,5); //startPage后紧跟的这个查询就是分页查询 List<Employee> emps = employeeService.getAll(); //使用PageInfo包装查询结果,只需要将pageInfo交给页面就可以 PageInfo pageInfo = new PageInfo<>(emps,5); //pageINfo封装了分页的详细信息,也可以指定连续显示的页数 map.put("pageInfo",pageInfo); return "list"; }</pre><br>
以上使用说明:
·在查询调用方法前声明分页信息(当前页,每页记录数)
·在查询调用方法对查询结果进行包装成PageInfo对象,也可以是定连续显示的页数,这也是常用功能。
注意:都是与查询方法紧挨着的,不要中间夹杂其它无关语句
之后把信息放在ModelAndView中就可以在前台访问了。
下面说一下为什么要把查询结果包装成PageInfo对象
3.PageInfo类说明
类源码(更多源码去github上查看即可):
- public class PageInfo<T> implements Serializable {
- private static final long serialVersionUID = 1L;
- //当前页
- private int pageNum;
- //每页的数量
- private int pageSize;
- //当前页的数量
- private int size;
- //由于startRow和endRow不常用,这里说个具体的用法
- //可以在页面中"显示startRow到endRow 共size条数据"
- //当前页面第一个元素在数据库中的行号
- private int startRow;
- //当前页面最后一个元素在数据库中的行号
- private int endRow;
- //总记录数
- private long total;
- //总页数
- private int pages;
- //结果集
- private List<T> list;
- //前一页
- private int prePage;
- //下一页
- private int nextPage;
- //是否为第一页
- private boolean isFirstPage = false;
- //是否为最后一页
- private boolean isLastPage = false;
- //是否有前一页
- private boolean hasPreviousPage = false;
- //是否有下一页
- private boolean hasNextPage = false;
- //导航页码数
- private int navigatePages;
- //所有导航页号
- private int[] navigatepageNums;
- //导航条上的第一页
- private int navigateFirstPage;
- //导航条上的最后一页
- private int navigateLastPage;
- public PageInfo() {
- }
- /**
- * 包装Page对象
- *
- * @param list
- */
- public PageInfo(List<T> list) {
- this(list, 8);
- }
- /**
- * 包装Page对象
- *
- * @param list page结果
- * @param navigatePages 页码数量
- */
- public PageInfo(List<T> list, int navigatePages) {
- if (list instanceof Page) {
- Page page = (Page) list;
- this.pageNum = page.getPageNum();
- this.pageSize = page.getPageSize();
- this.pages = page.getPages();
- this.list = page;
- this.size = page.size();
- this.total = page.getTotal();
- //由于结果是>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.list = list;
- this.size = list.size();
- this.total = list.size();
- this.startRow = 0;
- this.endRow = list.size() > 0 ? list.size() - 1 : 0;
- }
- if (list instanceof Collection) {
- this.navigatePages = navigatePages;
- //计算导航页
- calcNavigatepageNums();
- //计算前后页,第一页,最后一页
- calcPage();
- //判断页面边界
- judgePageBoudary();
- }
- }
- .......
- }
public class PageInfo<T> implements Serializable { private static final long serialVersionUID = 1L; //当前页 private int pageNum; //每页的数量 private int pageSize; //当前页的数量 private int size;//由于startRow和endRow不常用,这里说个具体的用法 //可以在页面中"显示startRow到endRow 共size条数据" //当前页面第一个元素在数据库中的行号 private int startRow; //当前页面最后一个元素在数据库中的行号 private int endRow; //总记录数 private long total; //总页数 private int pages; //结果集 private List<T> list; //前一页 private int prePage; //下一页 private int nextPage; //是否为第一页 private boolean isFirstPage = false; //是否为最后一页 private boolean isLastPage = false; //是否有前一页 private boolean hasPreviousPage = false; //是否有下一页 private boolean hasNextPage = false; //导航页码数 private int navigatePages; //所有导航页号 private int[] navigatepageNums; //导航条上的第一页 private int navigateFirstPage; //导航条上的最后一页 private int navigateLastPage; public PageInfo() { } /** * 包装Page对象 * * @param list */ public PageInfo(List<T> list) { this(list, 8); } /** * 包装Page对象 * * @param list page结果 * @param navigatePages 页码数量 */ public PageInfo(List<T> list, int navigatePages) { if (list instanceof Page) { Page page = (Page) list; this.pageNum = page.getPageNum(); this.pageSize = page.getPageSize(); this.pages = page.getPages(); this.list = page; this.size = page.size(); this.total = page.getTotal(); //由于结果是>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.list = list; this.size = list.size(); this.total = list.size(); this.startRow = 0; this.endRow = list.size() > 0 ? list.size() - 1 : 0; } if (list instanceof Collection) { this.navigatePages = navigatePages; //计算导航页 calcNavigatepageNums(); //计算前后页,第一页,最后一页 calcPage(); //判断页面边界 judgePageBoudary(); } }
.......
}这里只列出所有属性和构造方法,那么可以清晰的看到一些属性的含义,一些属性是如何初始化,并且初始化值是怎样的,更多详细情况可以自己去查看源码,都有中文注释
那么可以很方便在页面进行值的获取输出
4.在页面获取值(实现分页)
- <!--通过bootstrap的栅格系统布局-->
- <div class="container">
- <!--标题-->
- <div class="row">
- <div class="col-md-12">
- <h1>SSM-CRUD</h1>
- </div>
- </div>
- <!--按钮-->
- <div class="row">
- <div class="col-md-4 col-md-offset-8">
- <button class="btn btn-primary">新增</button>
- <button class="btn btn-danger">删除</button>
- </div>
- </div>
- <!--显示表格数据-->
- <div class="row">
- <div class="col-md-12">
- <table class="table table-hover">
- <tr>
- <th>#</th>
- <th>empName</th>
- <th>gender</th>
- <th>email</th>
- <th>deptName</th>
- <th>操作</th>
- </tr>
- <c:forEach items="${pageInfo.list}" var="emp">
- <tr>
- <th>${emp.empId}</th>
- <th>${emp.empName}</th>
- <th>${emp.gender=="M"?"男":"女" }</th>
- <th>${emp.email}</th>
- <th>${emp.department.deptName}</th>
- <th>
- <button class="btn btn-primary">
- <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span>
- 编辑
- </button>
- <button class="btn btn-danger">
- <span class="glyphicon glyphicon-trash" aria-hidden="true"></span>
- 删除
- </button>
- </th>
- </tr>
- </c:forEach>
- </table>
- </div>
- </div>
- <!--显示分页信息-->
- <div class="row">
- <!--文字信息-->
- <div class="col-md-6">
- 当前第 ${pageInfo.pageNum} 页.总共 ${pageInfo.pages} 页.一共 ${pageInfo.total} 条记录
- </div>
- <!--点击分页-->
- <div class="col-md-6">
- <nav aria-label="Page navigation">
- <ul class="pagination">
- <li><a href="${pageContext.request.contextPath}/emps?pn=1">首页</a></li>
- <!--上一页-->
- <li>
- <c:if test="${pageInfo.hasPreviousPage}">
- <a href="${pageContext.request.contextPath}/emps?pn=${pageInfo.pageNum-1}" aria-label="Previous">
- <span aria-hidden="true">«</span>
- </a>
- </c:if>
- </li>
- <!--循环遍历连续显示的页面,若是当前页就高亮显示,并且没有链接-->
- <c:forEach items="${pageInfo.navigatepageNums}" var="page_num">
- <c:if test="${page_num == pageInfo.pageNum}">
- <li class="active"><a href="#">${page_num}</a></li>
- </c:if>
- <c:if test="${page_num != pageInfo.pageNum}">
- <li><a href="${pageContext.request.contextPath}/emps?pn=${page_num}">${page_num}</a></li>
- </c:if>
- </c:forEach>
- <!--下一页-->
- <li>
- <c:if test="${pageInfo.hasNextPage}">
- <a href="${pageContext.request.contextPath}/emps?pn=${pageInfo.pageNum+1}"
- aria-label="Next">
- <span aria-hidden="true">»</span>
- </a>
- </c:if>
- </li>
- <li><a href="${pageContext.request.contextPath}/emps?pn=${pageInfo.pages}">尾页</a></li>
- </ul>
- </nav>
- </div>
- </div>
- </div>
<!--通过bootstrap的栅格系统布局--> <div class="container"><!--标题--> <div class="row"> <div class="col-md-12"> <h1>SSM-CRUD</h1> </div> </div> <!--按钮--> <div class="row"> <div class="col-md-4 col-md-offset-8"> <button class="btn btn-primary">新增</button> <button class="btn btn-danger">删除</button> </div> </div> <!--显示表格数据--> <div class="row"> <div class="col-md-12"> <table class="table table-hover"> <tr> <th>#</th> <th>empName</th> <th>gender</th> <th>email</th> <th>deptName</th> <th>操作</th> </tr> <c:forEach items="${pageInfo.list}" var="emp"> <tr> <th>${emp.empId}</th> <th>${emp.empName}</th> <th>${emp.gender=="M"?"男":"女" }</th> <th>${emp.email}</th> <th>${emp.department.deptName}</th> <th> <button class="btn btn-primary"> <span aria-hidden="true"></span> 编辑 </button> <button class="btn btn-danger"> <span aria-hidden="true"></span> 删除 </button> </th> </tr> </c:forEach> </table> </div> </div> <!--显示分页信息--> <div class="row"> <!--文字信息--> <div class="col-md-6"> 当前第 ${pageInfo.pageNum} 页.总共 ${pageInfo.pages} 页.一共 ${pageInfo.total} 条记录 </div> <!--点击分页--> <div class="col-md-6"> <nav aria-label="Page navigation"> <ul class="pagination"> <li><a href="http://t.zoukankan.com/${pageContext.request.contextPath}/emps?pn=1">首页</a></li> <!--上一页--> <li> <c:if test="${pageInfo.hasPreviousPage}"> <a href="http://t.zoukankan.com/${pageContext.request.contextPath}/emps?pn=${pageInfo.pageNum-1}" aria-label="Previous"> <span aria-hidden="true">«</span> </a> </c:if> </li> <!--循环遍历连续显示的页面,若是当前页就高亮显示,并且没有链接--> <c:forEach items="${pageInfo.navigatepageNums}" var="page_num"> <c:if test="${page_num == pageInfo.pageNum}"> <li class="active"><a href="http://t.zoukankan.com/jpfss-p-8706933.html#">${page_num}</a></li> </c:if> <c:if test="${page_num != pageInfo.pageNum}"> <li><a href="http://t.zoukankan.com/${pageContext.request.contextPath}/emps?pn=${page_num}">${page_num}</a></li> </c:if> </c:forEach> <!--下一页--> <li> <c:if test="${pageInfo.hasNextPage}"> <a href="http://t.zoukankan.com/${pageContext.request.contextPath}/emps?pn=${pageInfo.pageNum+1}" aria-label="Next"> <span aria-hidden="true">»</span> </a> </c:if> </li> <li><a href="http://t.zoukankan.com/${pageContext.request.contextPath}/emps?pn=${pageInfo.pages}">尾页</a></li> </ul> </nav> </div> </div>
</div>
最后显示:
PageHelpe开源地址
以上很常见的分页需求,可以非常方便的使用。
并且支持各种数据库,可以有多种方式进行引入插件,对于springBoot也有非常好的整合使用。
github项目地址:https://github.com/pagehelper/Mybatis-PageHelper
码云 项目地址:http://git.oschina.net/free/Mybatis_PageHelper
</div> </div>
Java并发编程(一) 两种实现多线程的方法(Thread,Runnable)
青蛙跳台阶(Fibonacci数列)
旋转数组的最小值
用两个栈实现队列
重建二叉树
二维数组中的查找
Lab 3-1
Lab 1-4
Lab 1-3
- 最新文章
HDU1166 敌兵布阵 splay
HDU1081 To The Max 最大子矩阵和
Codeforces 372B Counting Rectangles is Fun
Codeforces 354C Vasya and Beautiful Arrays
Codeforces 321B Ciel and Duel
Codeforces 379D New Year Letter
CCF 有趣的数
access数据库里面字段设置可以为空值和非必填的方法
There is no overloaded version of 'IntToStr' that can be called with these arguments 解决方法
常量不加引号报错提示‘参数**没有默认值’