您的位置:

如何正确使用PageHelper进行分页?

一、PageHelper简介

PageHelper是 Mybatis 著名开发者的开源工具包,用于对分页进行优化,PageHelper 在 Sql 执行过程中拦截 Sql 语句后自动进行分页,将分页语句封装成了 Page 对象,并且完整支持多种方言,例如 Oracle、MySQL、PostgreSQL 等。

使用 PageHelper 可以让我们不必关心复杂的分页逻辑,只需要在配置文件中指定分页参数即可,非常方便。

二、PageHelper入门使用

在使用 PageHelper 之前,需要先在 pom.xml 中引入相关依赖。

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>最新版本</version>
</dependency>
<!-- 数据库驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>最新版本</version>
</dependency>

在 SpringBoot 项目中,可以在 application.properties 文件中配置分页插件:

# 开启分页插件
pagehelper.helper-dialect=mysql
pagehelper.support-methods-arguments=true
pagehelper.reasonable=false
pagehelper.params=count=countSql

PageHelper 常用方法:

/**
 * 将 Page 对象传入查询接口,查询结束后 Page 对象自动填充分页信息
 * @param page 分页对象
 * @param param 查询参数
 * @return 查询结果集
 */
List<T> selectByPage(Page<T> page, Map<String, Object> param);

/**
 * 开始分页。需要紧跟在 select 方法后面,下一句 SQL 语句会被分页。
 * @param pageNum 页码
 * @param pageSize 分页大小
 */
PageHelper.startPage(pageNum, pageSize);

/**
 * 分页结束,释放资源。
 */
PageHelper.clearPage();

使用 PageHelper 进行分页基本流程:

  1. 调用 PageHelper.startPage() 方法,传入页码和分页大小。
  2. 执行查询,返回查询结果。
  3. 调用 PageHelper.stopPage() 方法,释放资源。

三、PageHelper高级使用

1. 多种分页方式

PageHelper 支持两种分页方式:

  1. 物理分页:查询所有数据后进行分页,使用简单。
  2. 逻辑分页:利用数据库本身的 limit 和 offset 等功能分页,查询速度更快。

默认情况下 PageHelper 使用逻辑分页,可以通过以下配置进行设置:

# 物理分页开关。设置为 true 后,所有的分页插件都会失效,变成物理分页。
pagehelper.offset-as-page-num=true
# 设置为 true 后,会将 RowBounds 第一个参数 offset 当成 pageNum 使用,可以用 RowBounds 实现物理分页。
pagehelper.row-bounds-with-count=true
# 默认值为 false,当该参数设置为 true 时,使用 RowBounds 分页时,会进行 count 查询。
pagehelper.row-bounds-with-count=true

2. 分页拦截

PageHelper 支持自定义拦截器进行分页逻辑拓展。继承 Interceptor 接口,重写干预方法,通过反射改写原始 Sql 实现分页功能。

// 定义自定义分页插件的类
public class CustomPageHelper extends PageInterceptor {
    // 重写进制的标签名
    @Override
    public String getLimitString(String sql, String s, int i, int i1) {
        return super.getLimitString(sql, "Tag_SG_limit", (i - 1) * i1, i1);
    }
}

// 配置类
@Configuration
public class MybatisInterceptorConfig {
    @Bean
    public CustomPageHelper pageHelper() {
        CustomPageHelper pageHelper = new CustomPageHelper();
        Properties properties = new Properties();
        properties.setProperty("supportMethodsArguments", "true");
        properties.setProperty("reasonable", "true");
        properties.setProperty("returnPageInfo", "check");
        properties.setProperty("params", "count=countSql");
        pageHelper.setProperties(properties);
        return pageHelper;
    }
}

// Mapper 接口
@Mapper
public interface UserMapper {
    @Select("SELECT * FROM user LIMIT #{pageNum},#{pageSize} Tag_SG_limit")
    List<User> selectAll(@Param("pageNum") int pageNum, @Param("pageSize") int pageSize);
}

四、PageHelper优点和缺点

优点:

  1. 使用简单,无需关注复杂分页逻辑。
  2. 支持多种方言,适用范围广。
  3. 自定义拦截器可进行分页逻辑拓展。

缺点:

  1. 虽然支持多种分页方式,但默认使用逻辑分页,影响速度。
  2. 分页信息封装在 Page 对象中,如果需要合并多个查询结果,合并分页信息比较麻烦。