Spring Boot 2.x 集成 PageHelper 分页插件

一、开始

Spring Boot 项目中集成 PageHelper 十分便捷,仅需如下几步即可快速使用分页功能。

1. 导入 Maven 依赖

没错,你没有看错,仅导入该依赖即可!

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.3.0</version>
</dependency>

2. 参数配置

这里仅配置一些基本参数,先感受下 PageHelper 的强大,下文再详细罗列下常用的配置参数。

# 分页配置参数
pagehelper:
  page-size-zero: true
  helper-dialect: mysql
  reasonable: true
  support-methods-arguments: true
  params: count=countSql

3. 快速使用

:star:注意:在集合查询前使用 PageHelper.startPage(pageNum, pageSize) ,并且 中间不能穿插执行任何其他 SQL 语句

@RequestMapping(value = "/select/{pageNum}/{pageSize}", method = RequestMethod.POST)
public PageInfo<Client> selectAllClients(@PathVariable("pageNum") int pageNum,
                                         @PathVariable("pageSize") int pageSize,
                                         @RequestBody Client client) {

    PageHelper.startPage(pageNum, pageSize);

    List<Client> clients = mapper.conditionalSelect(client);

    PageInfo<Client> pageInfos = new PageInfo<>(clients);

    return pageInfos;
}

4. 响应数据

① 前端页面渲染响应数据:

② Postman 发请求获取分页后的数据:

{
    "total": 10,
    "list": [
        {
            "id": 1,
            "name": "wyk",
            "source": "1",
            "industry": "1",
            "level": "1",
            "telephone": "1",
            "time": "2022-01-01T02:43:48.000+0000"
        },
        {
            "id": 2,
            "name": "dki",
            "source": "2",
            "industry": "2",
            "level": "2",
            "telephone": "2",
            "time": "2022-01-01T02:44:09.000+0000"
        },
        {
            "id": 3,
            "name": "agb",
            "source": "3",
            "industry": "3",
            "level": "3",
            "telephone": "3",
            "time": "2022-01-03T02:44:17.000+0000"
        }
    ],
    "pageNum": 1,
    "pageSize": 3,
    "size": 3,
    "startRow": 1,
    "endRow": 3,
    "pages": 4,
    "prePage": 0,
    "nextPage": 2,
    "isFirstPage": true,
    "isLastPage": false,
    "hasPreviousPage": false,
    "hasNextPage": true,
    "navigatePages": 8,
    "navigatepageNums": [
        1,
        2,
        3,
        4
    ],
    "navigateFirstPage": 1,
    "navigateLastPage": 4
}

二、进阶

1. 分页查询的高级用法

在实际项目运用中, PageHelper 的使用非常便利快捷,仅需 PageHelper + PageInfo 两个类即可完成分页功能。

然而往往这种最最简单的集成使用方式,却在很多实际应用场景中没有得到充分的开发利用。

首先看看最常见的使用方式:

public PageInfo<ResponseEntityDto> page(RequestParamDto param) {
	PageHelper.startPage(param.getPageNum(), param.getPageSize());
	List<ResponseEntityDto> list = mapper.selectByParam(param);
	PageInfo<ResponseEntityDto> pageInfo = new PageInfo<>(clients);
	return pageInfo;
}

在某种程度上而言,上述写法的确符合 PageHelper 的使用规范。

但是作为 Developer 的我们,往往只有在追求完美和极致的道路上才能够寻得突破与机遇;接下来我们看看如何合理规范地使用 PageHelper

public PageInfo<ResponseEntityDto> page(RequestParamDto param) {
    return PageHelper.startPage(param.getPageNum(), param.getPageSize())
        .doSelectPageInfo(() -> list(param));
}

public List<ResponseEntityDto> list(RequestParamDto param) {
    return mapper.selectByParam(param);
}

FAQ

Q:为什么要重新声明一个 list 函数?

A :往往在很多实际业务应用场景中, 分页查询 是基于大数据量的表格展示需求来进行的。然而很多时候,譬如:内部服务的互相调用, OpenAPI 的提供,甚至在某些前后端分离联调的业务场景中,是同样需要一个非分页集合查询接口来提供服务的。

Q: doSelectPageInfo 是什么?

AdoSelectPageInfoPageHelper.startPage() 函数返回的默认 Page 实例内置函数,该函数可以以 Lambda 的形式通过额外的 Function 来进行查询,而无需进行多余的 PageInfoList 转换。

2. PageHelper 参数配置

官方文档中提供了很多参数供我们配置,包括但不限于:

  • dialect
  • helperDialect
  • pageSizeZero
  • reasonable
  • params
  • supportMethodsArguments
  • closeConn
  • autoRuntimeDialect
  • offsetAsPageNum
  • rowBoundsWithCount

Spring Boot 项目中,直接到 application.yml 中进行配置即可。

pagehelper:
  # 分页插件会自动检测当前的数据库链接,自动选择合适的分页方式(可以不设置)
  # dialect: 
  # helper-dialect数据库设置后,auto-dialect设置为true不会改变helper-dialect的结果(默认为true)
  helper-dialect: mysql 
  auto-dialect: true 
  # 默认值false
  page-size-zero: false 
  # 分页合理化参数
  reasonable: true 
  # params: 
  # support-methods-arguments: 和params配合使用,具体可以看下面的讲解
  # 默认值为 false,该参数对使用 RowBounds 作为分页参数时有效。(一般用不着)
  offset-as-page-num: false 
  # 默认值为 false,RowBounds是否进行count查询(一般用不着)
  row-bounds-with-count: false 
  # 默认值为 false。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页
  auto-runtime-dialect: false 
  # 与auto-runtime-dialect配合使用
  close-conn: true 
  # 用于控制默认不带 count 查询的方法中,是否执行 count 查询,这里设置为true后,total会为-1
  default-count: false 

:如下序号与上面罗列的参数一一对应!

①:默认情况下会使用 PageHelper 方式进行分页,如果想要实现自己的分页逻辑,可以实现 Dialect(com.github.pagehelper.Dialect) 接口,然后配置该属性为实现类的全限定名称。(这里不推荐这样玩,毕竟使用别人的插件,何必多此一举呢?)

②: helper-dialect 配置时,可以使用下面的缩写值: oracle , mysql , mariadb , sqlite , hsqldb , postgresql , db2 , sqlserver , informix , h2 , sqlserver2012 , derby

③: page-size-zero 默认值为 false ,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit=0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)。

④: reasonable 是分页合理化参数(具备纠错机制),默认值为 false 。当该参数设置为 true 时, pageNum<=0 时会查询第一页, pageNum>pages (超过总数时)会查询最后一页。

⑤: params 为了支持 startPage(Object params) 方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值,可以配置 pageNum , pageSize , count , pageSizeZero , reasonable ,不配置映射的用默认值,默认值为 pageNum=pageNum;pageSize=pageSize;count=countSql; reasonable=reasonable;pageSizeZero=pageSizeZero

⑥: support-methods-arguments 支持通过 Mapper 接口参数来传递分页参数,默认值 false ,分页插件会从查询方法的 参数值 中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。

⑦: closeConn 默认值为 true 。当使用运行时动态数据源或没有设置 helperDialect 属性自动获取数据库类型时,会自动获取一个数据库连接,通过该属性来设置是否关闭获取的这个连接,默认 true 关闭,设置为 false 后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定。


作者:Author_Unknown
链接:Spring Boot(十二):Spring Boot 2.x 集成 PageHelper 分页插件 - 掘金