一、概述
使用分页插件来实现分页功能。好处是,分页条你可以自行排版,不受页面约束。(前端使用的是thymeleaf)
我使用的是spring boot 2.1.11.RELEASE,如果按照以下步骤不能实现分页,那可能是pagehelper的版本问题,更换版本试一下。
二、使用
首先在项目pom.xml中加入pagehelper插件的依赖
<!--pagehelper分页插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency>
配置
pagehelper.helper-dialect=mysql pagehelper.reasonable=true pagehelper.support-methods-arguments=true pagehelper.params=count=countSql
controller
//分页查询数据 @GetMapping("/usermanage") public String usermanage(Model model, @RequestParam(required = false,defaultValue="1",value="pageNum")Integer pageNum, @RequestParam(defaultValue="5",value="pageSize")Integer pageSize){ //为了程序的严谨性,判断非空: if(pageNum == null){ pageNum = 1; //设置默认当前页 } if(pageNum <= 0){ pageNum = 1; } if(pageSize == null){ pageSize = 5; //设置默认每页显示的数据数 } System.out.println("当前页是:"+pageNum+"显示条数是:"+pageSize); //1.引入分页插件,pageNum是第几页,pageSize是每页显示多少条,默认查询总数count PageHelper.startPage(pageNum,pageSize); //2.紧跟的查询就是一个分页查询-必须紧跟.后面的其他查询不会被分页,除非再次调用PageHelper.startPage try { List<User> userList = userService.getAll();//service查询所有的数据的接口 System.out.println("分页数据:"+userList); //3.使用PageInfo包装查询后的结果,5是连续显示的条数,结果list类型是Page<E> PageInfo<User> pageInfo = new PageInfo<User>(userList,pageSize); //4.使用model/map/modelandview等带回前端 model.addAttribute("pageInfo",pageInfo); }finally { PageHelper.clearPage(); //清理 ThreadLocal 存储的分页参数,保证线程安全 } //5.设置返回的jsp/html等前端页面 // thymeleaf默认就会拼串classpath:/templates/xxxx.html return "admin/user/list"; }
重要提示:
- 只有紧跟在PageHelper.startPage()方法后的第一个Mybatis的查询(Select)方法会被分页。
- 请不要在系统中配置多个分页插件(使用Spring时,mybatis-config.xml和Spring配置方式,请选择其中一种,不要同时配置多个分页插件)!
- 对于带有for update的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。
- 由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。
还有就分页插件支持以下几种调用方式(你任选),复制粘贴就好:
//第一种,RowBounds方式的调用 List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10)); //第二种,Mapper接口方式的调用,推荐这种使用方式。 PageHelper.startPage(1, 10); List<Country> list = countryMapper.selectIf(1); //第三种,Mapper接口方式的调用,推荐这种使用方式。 PageHelper.offsetPage(1, 10); List<Country> list = countryMapper.selectIf(1); //第四种,参数方法调用 //存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数 public interface CountryMapper { List<Country> selectByPageNumSize( @Param("user") User user, @Param("pageNum") int pageNum, @Param("pageSize") int pageSize); } //配置supportMethodsArguments=true //在代码中直接调用: List<Country> list = countryMapper.selectByPageNumSize(user, 1, 10); //第五种,参数对象 //如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页 //有如下 User 对象 public class User { //其他fields //下面两个参数名和 params 配置的名字一致 private Integer pageNum; private Integer pageSize; } //存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数 public interface CountryMapper { List<Country> selectByPageNumSize(User user); } //当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页 List<Country> list = countryMapper.selectByPageNumSize(user); //第六种,ISelect 接口方式 //jdk6,7用法,创建接口 Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() { @Override public void doSelect() { countryMapper.selectGroupBy(); } }); //jdk8 lambda用法 Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(()-> countryMapper.selectGroupBy()); //也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() { @Override public void doSelect() { countryMapper.selectGroupBy(); } }); //对应的lambda用法 pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> countryMapper.selectGroupBy()); //count查询,返回一个查询语句的count数 long total = PageHelper.count(new ISelect() { @Override public void doSelect() { countryMapper.selectLike(country); } }); //lambda total = PageHelper.count(()->countryMapper.selectLike(country));
前端thmeleaf
<!--显示分页信息--> <div class="modal-footer no-margin-top"> <div class="col-md-6"> 当前第 [[${pageInfo.pageNum}]]页,共 [[${pageInfo.pages}]] 页.一共 [[${pageInfo.total}]] 条记录 </div> <ul class="pagination pull-right no-margin"> <li th:if="${pageInfo.hasPreviousPage}"> <a th:href="'/usermanage?pageNum=1'">首页</a> </li> <li class="prev" th:if="${pageInfo.hasPreviousPage}"> <a th:href="'/usermanage?pageNum='+${pageInfo.prePage}"> <i class="ace-icon fa fa-angle-double-left"></i> </a> </li> <!--遍历条数--> <li th:each="nav:${pageInfo.navigatepageNums}"> <a th:href="'/usermanage?pageNum='+${nav}" th:text="${nav}" th:if="${nav != pageInfo.pageNum}"></a> <span style="font-weight: bold;background: #6faed9;" th:if="${nav == pageInfo.pageNum}" th:text="${nav}" ></span> </li> <li class="next" th:if="${pageInfo.hasNextPage}"> <a th:href="'/usermanage?pageNum='+${pageInfo.nextPage}"> <i class="ace-icon fa fa-angle-double-right"></i> </a> </li> <li> <a th:href="'/usermanage?pageNum='+${pageInfo.pages}">尾页</a> </li> </ul> </div> <div>当前页号:<span th:text="${pageInfo.pageNum}"></span></div> <div>每页条数:<span th:text="${pageInfo.pageSize}"></span></div> <div>起始行号:<span th:text="${pageInfo.startRow}"></span></div> <div>终止行号:<span th:text="${pageInfo.endRow}"></span></div> <div>总结果数:<span th:text="${pageInfo.total}"></span></div> <div>总页数:<span th:text="${pageInfo.pages}"></span></div> <hr /> <div>是否为第一页:<span th:text="${pageInfo.isFirstPage}"></span></div> <div>是否为最后一页:<span th:text="${pageInfo.isLastPage}"></span></div> <div>是否有前一页:<span th:text="${pageInfo.hasPreviousPage}"></span></div> <div>是否有下一页:<span th:text="${pageInfo.hasNextPage}"></span></div>
这是使用的thymeleaf语法来集成PageHelper实现的分页,很多从JSP转thymeleaf的同学可以直接使用这个代码就好了。
说明一点哈,这些都是需要引入CSS,js,jquery之类的,基本上版本通用的,PageHelper官网就有,不要不引入就来跟我说没有效果。
PageHelper官网:https://pagehelper.github.io/docs/howtouse/