前言
在使用传统的sql分页查询中,常用的做法就是在所有的select语句后面都加上limit来实现分页,如下图:
- --m的含义表示从数据的第m条开始查询(mysql中第一条数据m=0)
- --n的含义是从第m条数据开始往后查询n条数据
但是这样带来的问题有:
- 要改动的地方非常多,而且每个sql改动逻辑基本上一致;
- DAO层的查询逻辑要改动,要在原来查询之后执行查询 SELECT count(1) from ….. 查询数据总条数。
那么问题来了,是否有更加简单编辑的方式来解决以上问题呢?
答案是有的,Mybatis提供的了一个叫PageHelper的插件,解决了以上痛点。
PageHelper实现了通用的分页查询,支持mysql、Oracle、DB2、PostgreSQL等主流的数据库。
该项目托管于Github,地址为:MyBatis PageHelper Github地址
目前最新的版本为 5.1.10
一、PageHelper引入项目
1.maven引入PageHelper
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.10</version>
</dependency>
当然,我想在引入该依赖之前,Mybatis的依赖你一定引入了。
2.在application.properties中配置PageHelper相关配置
从上到下依次是:
pagehelper.helperDialect:设置方言
pagehelper.reasonable:是pageHelper里面自带的一个功能,叫做分页参数合理化。 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页; 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据。(pages指总页数)
pagehelper.supportMethodsArguments:supportMethodsArguments为true的情况下,PageHelper会分析传入的对象(QueryEntity),自动帮用户分析是否要进行分页。
到这里PageHelper的导入和配置就基本完成了。
二、PageHelper的使用
前提:在下面的例子项目中,因为涉及到的业务逻辑比较简单,所以entity和mapper层的代码都是通过 mybatis-generator即mybatis逆向工程插件生成的,具体关于 mybatis-generator的讲解可能下次更新。
1.写需要分页查询的接口:
public interface UserService {
public Boolean isAdminLeagel(Admin admin);
public Boolean isUserNameExistent(Admin admin);
public void addUser(UserInformation userInformation);
public PageInfo<UserInformation> getUserList(int pageNo, int pageSize);
public PageInfo<UserInformation> getUsersByNameLike(int pageNo,String userName);
}
需要分页查询的方法的返回值都是PageInfo<T>类型,PageInfo就是分页信息,查看其源码可以查看到各个属性。具体讲解下次更新。
2.在上面接口的实现类的具体方法中分页。
调用PageHelper的静态方法.startPage(int pageNum,int pageSize);即可开始操作。参数名也简单易懂好理解,这里不做解释。
看看具体实现代码:
@Override
public PageInfo<UserInformation> getUserList(int pageNo, int pageSize) {
PageHelper.startPage(pageNo,pageSize);
List<UserInformation> list = userInformationMapper.selectAll();
PageInfo<UserInformation> pages = new PageInfo<UserInformation>(list);
return pages;
}
简单快捷,只需要简单地调用.startPage()方法,设置页数及每页大小后,将查询结果list放入到pageInfo对象中,即可完成分页操作。
3.前端填写分页数据
上代码
<div class="col-md-10 ">
<form class="form-inline" >
<div class="form-group" th:action="@{/user/searchuser}" th:method="post">
<!--<label for="exampleInputName2">用户名:</label>-->
<input type="text" class="form-control input-sm" id="exampleInputName2" name="username" placeholder="用户名搜索"/>
</div>
<button type="submit" class="btn btn-success btn-sm"><span class="glyphicon glyphicon-search" aria-hidden="true"></span> </button>
</form>
<table class="table table-striped table-hover">
<thead>
<tr class="text text-center">
<th>用户名</th>
<th>邮箱</th>
<th>电话</th>
<th>微信</th>
<th>地址</th>
<th>注册时间</th>
<th>操作</th>
</tr>
</thead>
<tbody id="mytbody">
<tr class="text" th:each="user:${pages.list}">
<td th:text="${user.userName}">Column content</td>
<td th:text="${user.email}">Column content</td>
<td th:text="${user.phone}">Column content</td>
<td th:text="${user.wechat}">Column content</td>
<td th:text="${user.address}">Column content</td>
<td th:text="${#dates.format(user.registTime, 'yyyy-MMM-dd HH:mm')}">Column content</td>
<td>
<button class="btn btn-xs btn-primary">详情</button>
</td>
</tr>
</tbody>
</table>
<nav class="pull-right">
<ul class="pagination">
<li th:if="${pages.hasPreviousPage}" onclick="clicked(1)">
<a aria-label="Previous">
首页
</a>
</li>
<li th:if="${pages.hasPreviousPage}">
<a th:href="@{/user/listuser(pageNo=${pages.prePage})}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<li th:each="num:${pages.navigatepageNums}">
<a th:href="@{/user/listuser(pageNo=${num})}" th:text="${num}"></a>
</li>
<!--<li><a href="#">2</a></li>-->
<!--<li><a href="#">3</a></li>-->
<!--<li><a href="#">4</a></li>-->
<!--<li><a href="#">5</a></li>-->
<li th:if="${pages.hasNextPage}">
<a th:href="@{/user/listuser(pageNo=${pages.nextPage})}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
<li th:if="${pages.hasNextPage}">
<a th:href="@{/user/listuser(pageNo=${pages.pages})}" aria-label="Previous">
尾页
</a>
</li>
</ul>
</nav>
</div>
其中pages就是pageInfo对象,里面包含了所有的页面信息。
效果图:
这样简单的分页就做好了,本文章只提到分页的使用,并未详细的讲解其原理和过程,打算下次更新。
编程新人,如有问题,望各位大佬多指教。