面向关系型数据库的 SQL 查询和数据导出时,如果数据条数非常大,直接将所有数据一次性查出或者导出显然是不可行的。这时候就需要进行分页查询或分页导出,将查询或导出的数据按照指定大小分页加载或写入,从而提高查询或导出的效率。而分页查询或分页导出的实现过程比较繁琐,需要考虑很多细节问题,容易出错。因此,出现了一些支持分页查询或分页导出的插件或工具类,例如 MyBatis 的分页插件 PageHelper。
(4)高度自定义:PageHelper 支持自定义拦截器,并且提供了丰富的配置选项,可以根据实际需要进行自定义设置。
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency>此外,如果需要使用 PageHelper 的自动配置功能,还需要引入 MyBatis-Spring-Boot-Starter 和 Spring Boot Starter JDBC 或 MyBatis-Starter 等相关依赖。
# 堆代码 duidaima.com # PageHelper 配置 pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql
其中,helperDialect 属性指定了当前项目所使用的数据库类型,reasonable 属性指定了是否启用合理化查询(即优化分页查询性能),supportMethodsArguments 属性指定了是否支持接口参数来传递分页参数,params 属性指定了 PageHelper 的参数名称。
// 第 1 个参数为当前页码数,第 2 个参数为每页显示的条数 PageHelper.startPage(1, 10); List<User> userList = userDao.selectUserList(); // 通过 PageInfo 获取分页信息 PageInfo<User> pageInfo = new PageInfo<>(userList); System.out.println(pageInfo.getTotal());上述代码首先调用了 PageHelper 的 startPage 方法,传入了当前页码数和每页显示的条数,然后调用了 UserDao 的 selectUserList() 方法查询用户列表。最后通过 PageInfo 获取分页信息,包括总记录数、当前页码数、每页显示的条数等信息。
(3)文档不够丰富:PageHelper 的官方文档相对简单,部分功能使用方法没有详细介绍,需要开发者自行查询相关资料。
(4)分页参数设置:在使用 PageHelper 进行分页查询时,需要按照要求设置分页参数,如 pageNum 和 pageSize 等参数,否则可能会导致查询结果不正确。
// 堆代码 duidaima.com // 分页查询拦截器 public class PageInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 解析分页参数 Page<Object> page = getPageParam(invocation); // 生成分页 SQL String pageSql = generatePageSql(page, invocation); // 替换原始 SQL 语句为分页 SQL setSql(invocation, pageSql); // 执行分页查询 List<?> result = (List<?>) invocation.proceed(); // 生成分页信息 PageInfo<?> pageInfo = new PageInfo<>(result, page.getPageSize()); return pageInfo; } } // 获取分页参数 private Page<Object> getPageParam(Invocation invocation) { Object[] args = invocation.getArgs(); for (Object arg : args) { if (arg instanceof Page) { return (Page<Object>) arg; } } return null; } // 生成分页 SQL private String generatePageSql(Page<?> page, Invocation invocation) { MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0]; String sql = mappedStatement.getBoundSql(page).getSql(); Dialect dialect = getDialect(mappedStatement.getConfiguration().getEnvironment().getDataSource()); return dialect.generatePageSql(sql, page.getStartRow(), page.getPageSize()); } // 设置 SQL 语句 private void setSql(Invocation invocation, String sql) { Object[] args = invocation.getArgs(); MappedStatement mappedStatement = (MappedStatement) args[0]; BoundSql boundSql = mappedStatement.getBoundSql(args[1]); MetaObject metaObject = SystemMetaObject.forObject(boundSql); metaObject.setValue("sql", sql); }以上代码中,getPageParam() 方法用于获取传入的分页参数,generatePageSql() 方法用于根据当前数据库类型生成分页 SQL 语句,setSql() 方法用于将原始的 SQL 语句替换为分页 SQL 语句。此外,还需要实现 Dialect 接口来提供不同数据库类型的方言实现。