第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 测试分页接口。

相关推荐
captain3761 小时前
MyBatis操作数据库(入门2)
java·数据库·spring boot·后端·spring·mybatis
学长毕设4 小时前
基于SpringBoot的餐厅管理系统-附源码
java·spring boot·后端
paopaokaka_luck10 小时前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
软件技术NINI12 小时前
基于SpringBoot和Vue的摇滚乐鉴赏网站
vue.js·spring boot·后端·spring·html·毕业设计·毕设
学长毕设12 小时前
基于SpringBoot的校园礼服租赁系统的设计与实现
java·spring boot·后端
计算机毕设定制辅导-无忧学长13 小时前
《基于物品协同过滤的闲置书换购微信小程序设计开发》
java·vue.js·spring boot·微信小程序·uniapp·闲置书换购微信小程序·物品协同过滤算法
Best_Liu~13 小时前
SpringBoot全局日期格式化
java·spring boot·后端
RuoyiOffice13 小时前
SpringBoot3 + openGauss:RuoYi Office 登录、流程发布与用印填报适配实战
java·数据库·spring boot·opengauss·信创
Dwzun13 小时前
基于SpringBoot3+Vue3的油莎豆种植管理系统
java·前端·vue.js·spring boot·后端·python·计算机网络
学长毕设1 天前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端