Java MyBatis分页案例怎么实现

wen java案例 27

本文目录导读:

Java MyBatis分页案例怎么实现

  1. 物理分页(推荐) - 使用 PageHelper
  2. 手动实现物理分页
  3. 使用 MyBatis-Plus 分页
  4. 通用分页工具类
  5. 最佳实践建议

我来详细介绍 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;
    }
}

最佳实践建议

  1. 推荐使用 PageHelper:简单易用,自动拦截 SQL 添加分页
  2. 统一分页参数传递:使用 DTO 或 PageRequest 对象
  3. 合理设置默认值:pageNum=1, pageSize=10
  4. 限制最大分页大小:防止恶意查询
  5. 复杂查询建议使用 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 插件版本,它是最简单且功能最完善的分页实现方式。

抱歉,评论功能暂时关闭!