赞
踩
目录
本文环境:Spring boot 2.3.5 + Java jdk 8 + Mysql + Log4j2 + MyBatis 3.5.7 + PageHelper 5.2.1
PageHelper 官网:MyBatis 分页插件 PageHelper
PageHelper GitHub:GitHub - pagehelper/Mybatis-PageHelper: Mybatis通用分页插件
PageHelper 集成 Spring Boot:GitHub - pagehelper/pagehelper-spring-boot: pagehelper-spring-boot
1、PageHelper 分页插件支持任何复杂的单表、多表分页。
2、物理分页:支持常见的 12 种数据库:Oracle, MySql, MariaDB, SQLite, DB2, PostgreSQL, SqlServer 等。
3、多种分页方式:支持常见的RowBounds(PageRowBounds),PageHelper.startPage 方法调用,Mapper 接口参数调用,QueryInterceptor 拦截器方式。
4、Spring boot 项目推荐直接引用 pagehelper-spring-boot-starter 启动器:
- <!--mybatis 分页插件 pagehelper 内部依赖了 mybatis-spring-boot-starter 启动器 以及 com.github.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.3.1</version>
- </dependency>
5、pagehelper-spring-boot-starter 启动器的自动配置类与配置属性如下,默认情况下,导入依赖后即可进行分页,如果需要自定义配置,则可以从 PageHelperProperties 中查看配置项:
com.github.pagehelper.autoconfigure.PageHelperAutoConfiguration
com.github.pagehelper.autoconfigure.PageHelperProperties
6、application.yml 全局配置文件中 mybatis 分页插件 pageHelper 常用配置:
- #mybatis 分页插件 pageHelper 配置
- pagehelper:
- #支持通过 Mapper 接口参数来传递分页参数,为 true 时,分页插件会从查询方法的参数值中查找 pageNum、pageSize 参数的值进行自动分页。默认值 false.
- supportMethodsArguments: true
- #分页合理化参数,为 true 时,pageNum<=0 会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
- reasonable: true
- #设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0, 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型),默认值为 false,
- pageSizeZero: true
1、其实分页的关键是获取符合查询 sql 条件的总条数,只要有了它,再根据传入的参数 pageNum,pageSize 就能计算出任何想要的数据,比如总页数,上一页,下一页等等。
2、比如是在代码里面写 sql 时,则只需要在目标 sql 外面再包装一层,再查询一下 count(*) 即可获取到本 sql 的总条数,而 mybatis 的 sql 因为是在配置文件中或者在注解上,比较特殊,所以无法用常规手段获取。
3、一个 Controller 中总有几个查询的接口,让其实现分页非常简单,只需要在查询前开启分页:PageHelper.startPage,然后再返回结果后,包装 Page 对象 new PageInfo(List<T> list) 即可。
4、只有紧跟在 PageHelper.startPage、PageHelper.offsetPage 方法后的第一个 Mybatis 的查询(Select)方法会被分页,除非再次调用 PageHelper.startPage 或者调用 PageHelper.offsetPage。
- //控制层方法:http://localhost:8080/findByKeywordPage1?pageNum=2&pageSize=4
- @GetMapping("/findByKeywordPage1")
- public PageInfo findByKeywordPage1(String keyword, Integer pageNum, Integer pageSize) {
- pageNum = pageNum == null || pageNum <= 0 ? 0 : pageNum;
- pageSize = pageSize == null || pageSize <= 0L ? 0 : pageSize;
- /**
- * 1、PageHelper.startPage(int pageNum, int pageSize):开始分页,此时 XxxMapper 返回的集合是 {@link com.github.pagehelper.Page} 分页对象
- * total(总记录数) 等于 ((Page)list).getTotal();
- * 2、PageHelper.offsetPage:开始分页,底层与 startPage 是一样的.
- * 3、如果 pageNum 或者 pageSize 为 0,则不分页,默认查询所有,此时 XxxMapper 返回的集合不再是 {@link com.github.pagehelper.Page} 分页对象
- * 此时 size(当前页的数量)、total(总记录数) 都是等于普通的 list.size()
- * 4、只有紧跟在 PageHelper.startPage、PageHelper.offsetPage 方法后的第一个 Mybatis 的查询(Select)方法会被分页。
- */
- if (pageNum != 0 && pageSize != 0) {
- //PageHelper.startPage(pageNum, pageSize);
- PageHelper.offsetPage(pageNum, pageSize);
- }
- List<Dept> deptList = deptMapper.findByKeyword(keyword);
-
- /**
- * PageInfo(List<T> list):包装 Page 对象,默认导航页码为8
- * PageInfo(List<T> list, int navigatePages):包装 Page 对象,指定导航页码数量
- */
- PageInfo pageInfo = new PageInfo(deptList);
- return pageInfo;
- }
- //DeptMapper 接口:根据关键字模糊查询,默认查询所有
- List<Dept> findByKeyword(String keyword);
- <!-- DeptMapper.xml 映射 -->
- <!-- 根据关键字模糊查询,不为空时才拼 like 条件,否则默认查询所有.-->
- <select id="findByKeyword" resultType="com.wmx.hb.pojo.Dept" parameterType="string">
- select * from dept
- <where>
- <if test="keyword!=null">
- dname like concat('%',concat(#{keyword},'%')) or loc like concat('%',concat(#{keyword},'%'))
- </if>
- </where>
- order by deptno desc
- </select>
/hb/blob/master/src/main/java/com/wmx/hb/controller/DeptController.java
/hb/blob/master/src/main/java/com/wmx/hb/mapper/DeptMapper.java
/hb/blob/master/src/main/resources/myBatis/mapper/base/DeptMapper.xml
1、只要 XxxMapper 接口的方法中含有参数 pageNum、pageSize,则会自动进行分页,不需要在 XxxMapper.xml 中进行任何处理。
2、此种方式时必须配置 pagehelper.supportMethodsArguments=true,开启支持 Mapper 方法参数分页.
- //控制层方法
- @PostMapping("/findByDept")
- public PageInfo<Dept> findByDept(@RequestBody(required = false) Dept dept, Integer pageNum, Integer pageSize) {
- pageNum = pageNum == null || pageNum <= 0L ? 1 : pageNum;
- pageSize = pageSize == null || pageSize <= 0L ? 2 : pageSize;
-
- //此时必须配置 pagehelper.supportMethodsArguments=true,开启支持 Mapper 方法参数分页.
- //pageNum、pageSize 也可以直接是 dept 对象的属性,当 pageNum!= null && pageSize!= null 时,也会自动分页.
- List<Dept> deptList = deptMapper.findByDept(dept, pageNum, pageSize);
- PageInfo<Dept> pageInfo = new PageInfo<Dept>(deptList);
- return pageInfo;
- }
- /**DeptMapper 接口方法
- * 1、查询指定部门的信息,将实体对象中不为空的属性都作为 where 条件,默认查所有。
- * 2、使用 org.apache.ibatis.annotations.Param 注解可以为 XxxMapper 接口方法指定多个参数。
- * 3、多个参数会被封装成一个 map,map 的 key 是使用 @Param 注解指定的值,value 是参数值。
- * 4、如果是级联对象,则 XxxMapper.xml 映射文件中也是级联取值,如 dept.deptno、dept.dname,前提是 dept 不能为 null,否则异常.
- * 5、pageNum、pageSize 也可以直接是 dept 对象的属性,当 pageNum!= null && pageSize!= null 时,也会自动分页.
- *
- * @param dept
- * @param pageNum :查询的页码,从1开始
- * @param pageSize :每页显示的条数
- * @return
- */
- List<Dept> findByDept(@Param("dept") Dept dept, @Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
- <!--dept是对象,所以需要级联取值,必须不等于 null,才能级联取值-->
- <!--拼接 where 条件前进行参数是否为空判断。返回值类型指定为 List 中的元素类型-->
- <!--where 标签会自动删除内容开头的 and 或者 or 字符串 -->
- <select id="findByDept" resultType="com.wmx.hb.pojo.Dept">
- SELECT t1.deptno,t1.dname,t1.loc from dept t1
- <where>
- <if test="dept !=null and dept.deptno!=null">
- deptno = #{dept.deptno}
- </if>
- <if test="dept !=null and dept.dname!=null and dept.dname !=''">
- and dname like concat('%',concat(#{dept.dname},'%'))
- </if>
- <if test="dept !=null and dept.loc!=null and dept.loc!=''">
- and loc like concat('%',concat(#{dept.loc},'%'))
- </if>
- </where>
- </select>
1、写法和 PageHelper 方式差不多,如下所示:
- //控制层方法
- @GetMapping("/findByKeyword")
- public PageInfo<Dept> findByKeyword(String keyword, Integer pageNum, Integer pageSize) {
- pageNum = pageNum == null || pageNum <= 0 ? 0 : pageNum;
- pageSize = pageSize == null || pageSize <= 0L ? 0 : pageSize;
-
- //doSelectPage 返回的是 Page<E>对象,doSelectPageInfo 返回的是 PageInfo<E>对象.
- PageInfo<Dept> pageInfo = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(new ISelect() {
- @Override
- public void doSelect() {
- deptMapper.findByKeyword(keyword);
- }
- });
- return pageInfo;
- }
- // DeptMapper 接口方法:根据关键字模糊查询,默认查询所有
- List<Dept> findByKeyword(String keyword);
- <!-- DeptMapper.xml 映射文件:根据关键字模糊查询,不为空时才拼 like 条件,否则默认查询所有.-->
- <select id="findByKeyword" resultType="com.wmx.hb.pojo.Dept" parameterType="string">
- select * from dept
- <where>
- <if test="keyword!=null">
- dname like concat('%',concat(#{keyword},'%')) or loc like concat('%',concat(#{keyword},'%'))
- </if>
- </where>
- order by deptno desc
- </select>
1、PageInfo 是对 Page<E> 结果的包装,包含了整个分页的详细信息,如下所示。
2、pagehelper 的 pageinfo(分页信息) 中的许多属性实际开发中可能用不到,通常也不会直接返回 pageinfo,而是会返回自己封装的数据对象,比如会有状态码,提示信息等等,此时可以在工具类中添加方法用于从 pageinfo 中提取需要的数据。
protected long total; //总记录数 |
protected List<T> list; //结果集 |
private int pageNum; //当前页 |
private int pageSize; //每页的数量 |
private int size; //当前页的数量 |
//由于startRow和endRow不常用,这里说个具体的用法 //可以在页面中"显示startRow到endRow 共size条数据" //当前页面第一个元素在数据库中的行号 private long startRow; |
private long endRow; //当前页面最后一个元素在数据库中的行号 |
private int pages; //总页数 |
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; //导航条上的最后一页 |
{
"total": 12,
"list": [
{
"deptno": 4,
"dname": "事业部",
"loc": "沙"
},
{
"deptno": 3,
"dname": "sales",
"loc": "chicago"
},
{
"deptno": 2,
"dname": "research",
"loc": "dallas"
},
{
"deptno": 1,
"dname": "IOS开发部",
"loc": "长沙"
}
],
"pageNum": 3,
"pageSize": 4,
"size": 4,
"startRow": 9,
"endRow": 12,
"pages": 3,
"prePage": 2,
"nextPage": 0,
"isFirstPage": false,
"isLastPage": true,
"hasPreviousPage": true,
"hasNextPage": false,
"navigatePages": 8,
"navigatepageNums": [
1,
2,
3
],
"navigateFirstPage": 1,
"navigateLastPage": 3
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。