本文目录导读:

在Java开发中,整合分页插件最常用的场景是 MyBatis 搭配 PageHelper(一个非常流行的分页插件),以下是一个标准的整合案例。
核心思路
PageHelper 的工作原理是基于 MyBatis 的拦截器(Interceptor),在执行 SQL 查询之前,自动拦截并动态拼接上 LIMIT 分页语句,同时自动查询总记录数。
环境准备
假设你使用的是 Spring Boot + MyBatis 项目。
添加 Maven 依赖(pom.xml):
<!-- MyBatis 启动器 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- PageHelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>2.1.0</version> <!-- 注意版本兼容 -->
</dependency>
配置分页插件
Spring Boot 自动配置(推荐)
在 application.yml 或 application.properties 中配置:
pagehelper: helper-dialect: mysql # 数据库方言(自动识别或指定) reasonable: true # 启用合理化分页(页码<=0时查第一页,>总页数时查最后一页) supportMethodsArguments: true # 支持通过 Mapper 接口参数来传递分页参数 params: count=countSql # 从参数中获取 count 查询的 SQL
Java 配置类(手动配置)
如果不想用 starter,可以通过 @Configuration 手动注入:
@Configuration
public class MyBatisConfig {
@Bean
public PageInterceptor pageInterceptor() {
PageInterceptor interceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("helperDialect", "mysql");
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
interceptor.setProperties(properties);
return interceptor;
}
}
Service 层使用
分页插件的核心用法是在 查询之前 调用 PageHelper.startPage()。
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
/**
* 分页查询用户
* @param pageNum 当前页码(从1开始)
* @param pageSize 每页条数
* @return PageInfo 包含了分页信息和数据
*/
public PageInfo<User> findUsersByPage(int pageNum, int pageSize) {
// 1. 设置分页参数(必须放在查询语句之前)
PageHelper.startPage(pageNum, pageSize);
// 2. 执行正常的查询(PageHelper会自动拦截并拼接 limit 语句)
List<User> userList = userMapper.findAllUsers();
// 3. 将查询结果封装成 PageInfo 对象
// PageInfo 包含了:当前页数据、总记录数、总页数、是否有下一页等信息
return new PageInfo<>(userList);
}
}
Controller 层调用
@RestController
@RequestMapping("/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/page")
public Result<PageInfo<User>> getUsersByPage(
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
PageInfo<User> pageInfo = userService.findUsersByPage(pageNum, pageSize);
return Result.success(pageInfo);
}
}
前端返回的 JSON 示例
PageInfo 对象序列化后,前端会得到如下结构:
{
"pageNum": 1,
"pageSize": 10,
"total": 85, // 总记录数
"pages": 9, // 总页数
"list": [ // 当前页数据
{ "id": 1, "name": "张三" },
{ "id": 2, "name": "李四" }
],
"isFirstPage": true,
"isLastPage": false,
"hasPreviousPage": false,
"hasNextPage": true
}
重要注意事项
-
线程安全:
PageHelper.startPage()使用ThreadLocal,分页参数与当前线程绑定。必须保证在同一个线程中,且查询之后立即使用,不能跨方法或跨线程。 -
仅对紧随其后的第一个查询生效:
// 正确 PageHelper.startPage(1, 10); List<User> list = userMapper.selectAll(); // 这个查询会被分页 // 错误(中间不能有其它查询) PageHelper.startPage(1, 10); userMapper.countAll(); // 这个查询也会被分页,导致数据错乱 List<User> list = userMapper.selectAll(); // 这个不会被分页
-
嵌套查询:Mapper 方法中包含
@Select或 XML 中的<association>等嵌套查询,分页插件可能无法正确处理总条数,建议避免使用嵌套查询进行分页。 -
性能:分页插件会自动生成
count查询(SELECT count(0) FROM ...),如果表数据量极大,count查询本身可能会比较慢,可考虑使用其他优化方案(如缓存总条数)。
- 加依赖:
pagehelper-spring-boot-starter - 配属性:
application.yml中配置数据库方言 - 写代码:在 Service 方法中,查询前调用
PageHelper.startPage(pageNum, pageSize),查询后使用new PageInfo<>(list)获取分页结果
这是目前 Java 后端最主流、最简洁的分页插件整合方式。