本文目录导读:

我来详细介绍 MyBatis 分页的几种实现方式:
物理分页(推荐) - 使用 PageHelper
Maven 依赖
<!-- PageHelper 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>
配置 PageHelper
# application.yml pagehelper: helper-dialect: mysql reasonable: true support-methods-arguments: true params: count=countSql
Service 层实现
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
/**
* 分页查询用户
* @param pageNum 当前页码
* @param pageSize 每页条数
* @return 分页结果
*/
public PageInfo<User> getUserByPage(int pageNum, int pageSize) {
// 1. 设置分页参数
PageHelper.startPage(pageNum, pageSize);
// 2. 执行查询(MyBatis 会自动拦截并添加分页)
List<User> userList = userMapper.selectAll();
// 3. 包装分页信息
return new PageInfo<>(userList);
}
}
Mapper 接口
@Mapper
public interface UserMapper {
// 普通的查询方法,不需要手动处理分页
List<User> selectAll();
// 带条件的分页查询
List<User> selectByCondition(UserQuery query);
}
Mapper XML
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper">
<!-- 普通查询,不需要LIMIT -->
<select id="selectAll" resultType="com.example.entity.User">
SELECT * FROM user ORDER BY id DESC
</select>
<!-- 带条件的分页查询 -->
<select id="selectByCondition" resultType="com.example.entity.User">
SELECT * FROM user
<where>
<if test="username != null and username != ''">
AND username LIKE CONCAT('%', #{username}, '%')
</if>
<if test="status != null">
AND status = #{status}
</if>
</where>
ORDER BY id DESC
</select>
</mapper>
Controller 层
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/page")
public Result<PageInfo<User>> getUserPage(
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
PageInfo<User> pageInfo = userService.getUserByPage(pageNum, pageSize);
return Result.success(pageInfo);
}
}
前端接收的分页数据格式
{
"code": 200,
"message": "success",
"data": {
"pageNum": 1, // 当前页码
"pageSize": 10, // 每页条数
"size": 10, // 当前页数据条数
"total": 100, // 总记录数
"pages": 10, // 总页数
"list": [ // 数据列表
{
"id": 1,
"username": "张三",
"email": "zhangsan@example.com"
}
],
"isFirstPage": true, // 是否为第一页
"isLastPage": false, // 是否为最后一页
"hasPreviousPage": false,
"hasNextPage": true
}
}
手动实现物理分页
分页参数类
@Data
public class PageRequest {
private int pageNum = 1;
private int pageSize = 10;
public int getOffset() {
return (pageNum - 1) * pageSize;
}
}
Mapper XML(手动添加LIMIT)
<select id="selectPage" resultType="com.example.entity.User">
SELECT * FROM user
ORDER BY id DESC
LIMIT #{offset}, #{pageSize}
</select>
<select id="count" resultType="java.lang.Long">
SELECT COUNT(*) FROM user
</select>
Service 实现
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public Map<String, Object> getUserPage(PageRequest pageRequest) {
// 查询总数
long total = userMapper.count();
// 查询分页数据
List<User> list = userMapper.selectPage(
pageRequest.getOffset(),
pageRequest.getPageSize()
);
// 封装分页信息
Map<String, Object> result = new HashMap<>();
result.put("list", list);
result.put("total", total);
result.put("pageNum", pageRequest.getPageNum());
result.put("pageSize", pageRequest.getPageSize());
result.put("pages", (int) Math.ceil((double) total / pageRequest.getPageSize()));
return result;
}
}
使用 MyBatis-Plus 分页
配置
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
Service 实现
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public IPage<User> getUserPage(int current, int size) {
// 创建分页对象
Page<User> page = new Page<>(current, size);
// 方式一:无条件分页查询
return userMapper.selectPage(page, null);
// 方式二:带条件的分页查询
// QueryWrapper<User> wrapper = new QueryWrapper<>();
// wrapper.like("username", "张");
// return userMapper.selectPage(page, wrapper);
}
}
通用分页工具类
@Data
public class PageResult<T> {
private List<T> list;
private long total;
private int pageNum;
private int pageSize;
private int pages;
private boolean isFirstPage;
private boolean isLastPage;
public static <T> PageResult<T> of(List<T> list, long total, int pageNum, int pageSize) {
PageResult<T> result = new PageResult<>();
result.setList(list);
result.setTotal(total);
result.setPageNum(pageNum);
result.setPageSize(pageSize);
result.setPages((int) Math.ceil((double) total / pageSize));
result.setFirstPage(pageNum == 1);
result.setLastPage(pageNum >= result.getPages());
return result;
}
}
最佳实践建议
- 推荐使用 PageHelper:简单易用,自动拦截 SQL 添加分页
- 统一分页参数传递:使用 DTO 或 PageRequest 对象
- 合理设置默认值:pageNum=1, pageSize=10
- 限制最大分页大小:防止恶意查询
- 复杂查询建议使用 PageHelper:避免手动编写 LIMIT 和 COUNT
// 限制最大分页大小
@GetMapping("/page")
public Result<PageInfo<User>> getUserPage(
@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
// 限制最大分页大小
if (pageSize > 100) {
pageSize = 100;
}
PageInfo<User> pageInfo = userService.getUserByPage(pageNum, pageSize);
return Result.success(pageInfo);
}
这样,你就有了完整的 MyBatis 分页实现方案,推荐使用 PageHelper 插件版本,它是最简单且功能最完善的分页实现方式。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播