资讯动态

SpringBoot与MyBatis-Plus分页查询实战指南

发布时间:2026/10/14 13:54:46 来源:尧图企业网站定制
1. 分页查询的技术背景与价值在业务系统开发中数据分页是最基础却至关重要的功能模块。我经历过多个企业级项目发现无论管理系统还是移动应用只要涉及数据展示就必然需要分页支持。传统JDBC分页需要手动计算limit/offset而MyBatis-Plus的分页插件让这一切变得优雅高效。分页技术的核心价值在于性能优化避免一次性加载海量数据导致内存溢出用户体验前端表格、列表需要分页导航控件系统稳定性防止单次查询拖垮数据库SpringBoot与MyBatis-Plus的组合是目前Java领域实现分页的黄金方案。经过多个项目实战验证这种方案具有配置简单、性能稳定、扩展性强三大优势。下面通过完整案例演示如何快速实现生产级分页功能。2. 环境准备与基础配置2.1 项目依赖配置首先在pom.xml中添加必要依赖SpringBoot 2.7.x示例dependencies !-- SpringBoot Starter -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- MyBatis-Plus Starter -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.2/version /dependency !-- 数据库驱动以MySQL为例 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency /dependencies注意MyBatis-Plus版本建议使用3.5.x以上其分页插件经过深度优化解决了早期版本的若干边界问题。2.2 分页插件配置在SpringBoot启动类或配置类中添加分页插件Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); // 添加分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }关键参数说明DbType.MYSQL指定数据库类型支持Oracle、PostgreSQL等插件默认采用逻辑分页转物理分页策略自动识别优化count查询语句3. 核心分页实现详解3.1 分页查询Service实现以用户管理为例创建分页查询服务Service public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService { Override public PageUser pageList(PageParam param) { // 构建分页条件 PageUser page new Page(param.getPageNum(), param.getPageSize()); // 构建查询条件 LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.like(StringUtils.isNotBlank(param.getKeyword()), User::getName, param.getKeyword()); wrapper.eq(param.getStatus() ! null, User::getStatus, param.getStatus()); // 执行分页查询 return baseMapper.selectPage(page, wrapper); } }3.2 分页参数封装建议统一封装分页参数对象Data public class PageParam { ApiModelProperty(当前页码) private Long pageNum 1L; ApiModelProperty(每页条数) private Long pageSize 10L; ApiModelProperty(搜索关键词) private String keyword; ApiModelProperty(状态筛选) private Integer status; public void validate() { if (pageNum 1) pageNum 1L; if (pageSize 100) pageSize 100L; } }经验pageSize建议设置最大值限制如100防止恶意请求导致内存溢出3.3 控制器层封装统一分页响应格式RestController RequestMapping(/user) public class UserController { Autowired private UserService userService; GetMapping(/page) public RPageResultUser page(PageParam param) { param.validate(); PageUser page userService.pageList(param); return R.success(PageResult.build(page)); } } // 统一分页响应结构 Data public class PageResultT { private ListT records; private Long total; private Long size; private Long current; public static T PageResultT build(PageT page) { PageResultT result new PageResult(); result.setRecords(page.getRecords()); result.setTotal(page.getTotal()); result.setSize(page.getSize()); result.setCurrent(page.getCurrent()); return result; } }4. 高级功能与性能优化4.1 自定义分页SQL对于复杂查询可在Mapper中自定义SQL!-- UserMapper.xml -- select idselectUserPage resultTypeUser SELECT * FROM user WHERE deleted 0 if testparam.keyword ! null and param.keyword ! AND name LIKE CONCAT(%, #{param.keyword}, %) /if ORDER BY create_time DESC /selectJava接口定义public interface UserMapper extends BaseMapperUser { PageUser selectUserPage(PageUser page, Param(param) PageParam param); }4.2 分页性能优化技巧Count查询优化// 在分页参数中设置不执行count查询 PageUser page new Page(pageNum, pageSize, false);索引优化确保排序字段如create_time有索引复合查询条件建立联合索引大表分页优化-- 使用子查询优化深分页 SELECT * FROM user WHERE id (SELECT id FROM user ORDER BY id LIMIT 100000, 1) LIMIT 105. 常见问题排查指南5.1 分页失效问题现象分页参数未生效返回全部数据排查步骤检查是否配置了分页插件确认Page对象作为第一个参数查看执行的SQL日志是否包含LIMIT5.2 总数统计不准解决方案// 手动指定count语句 page.setOptimizeCountSql(false); page.setCountId(selectCountCustom);5.3 排序异常正确用法wrapper.orderByAsc(User::getCreateTime); wrapper.orderByDesc(age); // 字段名写法踩坑记录避免在Wrapper中混用Lambda和字符串字段名写法会导致排序失效6. 前端对接实战建议6.1 Axios请求示例async function loadPage(params) { const res await axios.get(/user/page, { params }) return { data: res.data.records, total: res.data.total, current: res.data.current, size: res.data.size } }6.2 Ant Design Vue表格集成template a-table :columnscolumns :data-sourcedata :paginationpagination changehandleTableChange / /template script export default { methods: { async handleTableChange(pagination) { const pager { ...this.pagination } pager.current pagination.current this.pagination pager await this.loadData() } } } /script在实际项目中分页查询往往会遇到各种边界情况。经过多个版本迭代我总结出最稳定的配置方案是MyBatis-Plus 3.5.x PageHelper模式二选一对于千万级数据表建议采用游标分页方案。分页看似简单但要做好性能与稳定性的平衡还需要根据实际业务场景不断调优。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑