MyBatis-Plus分页查询实现与优化技巧

📅 2026/7/27 12:11:29
MyBatis-Plus分页查询实现与优化技巧
1. MyBatis-Plus分页查询实现详解作为Java后端开发中最常用的ORM框架之一MyBatis-Plus在分页查询方面提供了非常便捷的解决方案。我在多个电商和ERP系统中实际使用过MP的分页功能今天就来详细分享下它的实现原理和实战技巧。1.1 为什么需要分页查询当数据量达到万级甚至百万级时一次性查询所有数据会导致内存溢出风险网络传输压力大前端渲染性能下降用户体验差加载时间长MyBatis-Plus通过内置的分页插件可以轻松实现物理分页真分页相比逻辑分页假分页性能更好。2. 基础环境配置2.1 添加依赖首先确保项目中已经引入MyBatis-Plus核心依赖dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency2.2 配置分页插件在Spring Boot配置类中添加分页拦截器Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); // 添加分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }注意DbType需要根据实际数据库类型设置支持MySQL、Oracle、PostgreSQL等主流数据库3. 基础分页实现3.1 使用Page对象最基础的分页查询方式// 构建分页参数 PageUser page new Page(1, 10); // 当前页每页条数 // 执行查询 PageUser result userMapper.selectPage(page, null); // 获取分页数据 ListUser records result.getRecords(); // 当前页数据 long total result.getTotal(); // 总记录数3.2 带条件的分页查询添加查询条件LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.like(User::getName, 张) .gt(User::getAge, 18); PageUser page new Page(1, 10); userMapper.selectPage(page, wrapper);4. 高级分页技巧4.1 自定义分页SQL对于复杂查询可以在Mapper中定义自己的分页方法Select(SELECT * FROM user WHERE age #{age}) IPageUser selectByAge(IPageUser page, Param(age) Integer age);调用方式PageUser page new Page(1, 10); userMapper.selectByAge(page, 18);4.2 分页优化建议索引优化确保分页字段有索引**避免SELECT ***只查询需要的字段深度分页优化-- 普通分页 SELECT * FROM user LIMIT 100000, 10; -- 优化后 SELECT * FROM user WHERE id 100000 LIMIT 10;对应MP实现wrapper.gt(User::getId, lastId) .last(LIMIT size);5. 常见问题解决5.1 分页失效问题可能原因未配置分页插件自定义SQL未使用IPage参数拦截器顺序问题解决方案// 确保拦截器配置正确 Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; }5.2 性能问题当单页数据量过大时如500条减少每页条数使用游标分页添加合适的索引6. 实战经验分享统一分页响应封装统一的分页返回对象public class PageResultT { private Long current; private Long size; private Long total; private ListT records; }前端分页参数处理public PageT buildPage(PageParam param) { return new Page(param.getCurrent(), param.getSize()); }多表联查分页Select(SELECT u.*, d.dept_name FROM user u LEFT JOIN dept d ON u.dept_id d.id) IPageUserVO selectUserWithDept(IPageUserVO page);7. 最新特性MyBatis-Plus 3.5.7新增功能支持JSQLParser 4.3优化count查询修复了多租户与分页插件的兼容性问题使用建议dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.7/version /dependency8. 日志与调试8.1 打印完整SQL配置application.ymlmybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl8.2 SQL填充插件实现SQL注入处理器public class MySqlInjector extends DefaultSqlInjector { Override public ListAbstractMethod getMethodList(Class? mapperClass) { ListAbstractMethod methodList super.getMethodList(mapperClass); methodList.add(new SelectPageByExample()); return methodList; } }9. 性能对比测试环境MySQL 8.0100万数据量分页方式平均耗时(ms)LIMIT分页1200游标分页350ID范围分页15010. 最佳实践对于后台管理系统推荐每页20-50条数据移动端建议每页10-20条导出功能建议使用流式查询定期优化表索引我在实际项目中发现合理使用MyBatis-Plus的分页功能配合前端虚拟滚动等技术可以显著提升大数据量下的系统性能。特别是在处理百万级数据报表时正确的分页策略能让查询时间从秒级降到毫秒级。