第11节:分页查询(MyBatis 实现分页,后端最常用功能)

第11节:分页查询(MyBatis 实现分页,后端最常用功能)

知识点讲解

日常管理系统几乎都要分页:数据量大的时候,不能一次性把全部数据查出来,会占用内存、网络带宽。

分页核心两个参数:

  • pageNum:当前页码(第几页)
  • pageSize:每页多少条数据
    返回结果需要包含:总条数、总页数、当前页数据列表

示例:pageNum=1,pageSize=2 → 查询第 1 页,每页 2 条记录

两种分页方案:

  1. 原生 MyBatis 手写 SQL 分页(本次讲,底层 LIMIT),适合理解原理
  2. MyBatis-Plus 分页插件(后续拓展)

步骤 1:新建分页返回实体 PageResult.java

包路径:com.zzs.szyt.common

复制代码
package com.zzs.szyt.common;

import lombok.Data;
import java.util.List;

/**
 * 分页统一返回对象
 */
@Data
public class PageResult<T> {
    // 当前页数据列表
    private List<T> records;
    // 总记录数
    private Long total;
    // 当前页码
    private Integer pageNum;
    // 每页条数
    private Integer pageSize;
    // 总页数
    private Integer pages;
}

步骤 2:新建分页查询参数实体 PageQuery.java

包路径:com.zzs.szyt.common

复制代码
package com.zzs.szyt.common;

import jakarta.validation.constraints.Min;
import lombok.Data;

/**
 * 分页查询入参
 */
@Data
public class PageQuery {
    @Min(value = 1, message = "页码不能小于1")
    private Integer pageNum = 1; // 默认第1页

    @Min(value = 1, message = "每页条数不能小于1")
    private Integer pageSize = 2; // 默认每页2条
}

步骤 3:UserMapper 新增分页查询方法 + 统计总数方法

打开 UserMapper.java 接口,增加两个抽象方法:

复制代码
/**
 * 分页查询用户
 * @param pageNum 页码
 * @param pageSize 每页条数
 * @return 用户列表
 */
List<User> selectUserPage(@Param("pageNum") Integer pageNum, @Param("pageSize") Integer pageSize);

/**
 * 查询用户总数量
 * @return 总条数
 */
Long selectUserCount();

⚠️ @Param 注解:MyBatis 中把参数名字传给 XML 文件,不要漏

步骤 4:UserMapper.xml 增加分页 SQL 和统计 SQL

打开 resources/mapper/UserMapper.xml,新增两个标签

复制代码
<!-- 分页查询 -->
<select id="selectUserPage" resultType="com.zzs.szyt.entity.User">
    SELECT id,name,age FROM user
    LIMIT #{pageNum}, #{pageSize}
</select>

<!-- 查询总记录数 -->
<select id="selectUserCount" resultType="java.lang.Long">
    SELECT COUNT(*) FROM user
</select>

MySQL LIMIT 语法:LIMIT offset,size

offset = (pageNum -1)*pageSize

注意!上面 XML 我写的 #{pageNum} 是偏移量,Controller 里要手动计算偏移量,不要直接传 pageNum 进去!

步骤 5:UserController 新增分页接口

复制代码
/**
 * 用户分页查询 GET /user/page
 * @param pageQuery 分页参数
 * @return 分页结果
 */
@GetMapping("/page")
public Result<PageResult<User>> userPage(@Valid PageQuery pageQuery){
    // 1.计算偏移量 offset = (当前页码-1)*每页条数
    int offset = (pageQuery.getPageNum() - 1) * pageQuery.getPageSize();
    // 2.分页查询数据列表
    List<User> userList = userMapper.selectUserPage(offset, pageQuery.getPageSize());
    // 3.查询总条数
    Long total = userMapper.selectUserCount();

    // 4.组装分页返回对象
    PageResult<User> pageResult = new PageResult<>();
    pageResult.setRecords(userList);
    pageResult.setTotal(total);
    pageResult.setPageNum(pageQuery.getPageNum());
    pageResult.setPageSize(pageQuery.getPageSize());
    // 计算总页数  total / pageSize,向上取整
    int pages = (int) Math.ceil((double)total / pageQuery.getPageSize());
    pageResult.setPages(pages);

    return Result.success(pageResult);
}

步骤 6:测试(Postman / 浏览器 GET 请求)

接口地址:http://localhost:8080/user/page?pageNum=1&pageSize=2

预期返回 JSON:

复制代码
{
    "code":200,
    "msg":"操作成功",
    "data":{
        "records": [
            {"id":1,"name":"张三","age":20},
            {"id":2,"name":"李四","age":22}
        ],
        "total":2,
        "pageNum":1,
        "pageSize":2,
        "pages":1
    }
}

多组测试场景

  1. 不传参数:http://localhost:8080/user/page,自动使用默认 pageNum=1,pageSize=2
  2. pageNum 传 0:触发参数校验,返回 {"code":500,"msg":"页码不能小于1","data":null}
  3. pageNum=1,pageSize=1:只返回第一条数据

拓展思考:分页接口也可以加上 Redis 缓存,你可以尝试自己加上,先完成基础分页测试。

任务

把上面代码依次新建 / 修改,重启项目,用浏览器或者 Postman 测试分页接口。

相关推荐
光依旧4 小时前
MCP实战手记系列(十):MCP Server高可用实战
spring boot·高可用·nginx负载均衡·redis哨兵·mcp·微服务容错·resilience4j熔断
省钱兄--zs7 小时前
西安24小时自助健身房解决方案实战:系统开发与部署全流程指南
java·spring boot·系统架构·intellij-idea·需求分析
ly76899 小时前
Spring Boot 集成 Elasticsearch 的生产实践:客户端选型、索引生命周期与批量写入容错
spring boot·elasticsearch·索引生命周期·java api client·批量写入
程序猿_极客9 小时前
【免费】分享一套优质的基于SpringBoot的服装商城管理系统的设计与实现(带可视化图表、协同过滤功能),源码+文档+视频详解(讲解)
java·spring boot·后端·服装商城管理系统
bug菌10 小时前
🤔同事突然问我:Spring的注解 @Component 和 @Service 有何不同?
java·spring boot·后端
Lonely丶墨轩11 小时前
用 Vue + Spring Boot + Python 做一个 AI 双人海龟汤游戏:从出题、联机到自动审稿等核心技术设计与实现
spring boot·后端·游戏
她的男孩12 小时前
打印模板草稿能保存,一点发布就报主从关系:我们把校验拆成了两档
java·spring boot·后端
wno70413 小时前
Spring Boot整合Quartz
java·spring boot·后端
萧瑟余晖14 小时前
Spring Boot Actuator监控运维详解
spring boot
vipxieliang16 小时前
ValidX 财务系统发票验证:发票号、税号、金额校验
java·spring boot