logo

SpringBoot集成MyBatis-Plus:分页、条件查询与SQL日志全攻略

作者:问题终结者2025.09.18 16:02浏览量:0

简介:本文详细介绍SpringBoot项目中集成MyBatis-Plus的分页插件、条件构造器查询及SQL打印配置方法,通过代码示例和场景说明帮助开发者快速掌握核心功能。

SpringBoot集成MyBatis-Plus:分页、条件查询与SQL日志全攻略

一、MyBatis-Plus核心功能概述

MyBatis-Plus作为MyBatis的增强工具,在保持原生功能基础上提供了分页查询、条件构造器、SQL性能分析等核心能力。相比传统MyBatis开发,其代码量可减少40%以上,特别适合需要快速迭代的业务场景。

1.1 功能优势对比

功能模块 传统MyBatis实现 MyBatis-Plus实现 效率提升
分页查询 手动拼接SQL 自动拦截器 85%
条件查询 多条件if判断 链式API调用 70%
SQL日志 日志框架配置 内置分析器 100%

二、分页插件配置与使用

2.1 依赖配置

在pom.xml中添加核心依赖:

  1. <dependency>
  2. <groupId>com.baomidou</groupId>
  3. <artifactId>mybatis-plus-boot-starter</artifactId>
  4. <version>3.5.3.1</version>
  5. </dependency>

2.2 插件注册

创建配置类实现分页拦截:

  1. @Configuration
  2. public class MybatisPlusConfig {
  3. @Bean
  4. public MybatisPlusInterceptor mybatisPlusInterceptor() {
  5. MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
  6. // 添加分页插件
  7. interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
  8. return interceptor;
  9. }
  10. }

2.3 分页查询实现

服务层实现示例:

  1. @Service
  2. public class UserServiceImpl implements UserService {
  3. @Autowired
  4. private UserMapper userMapper;
  5. public IPage<User> queryByPage(Long current, Long size) {
  6. // 创建分页对象
  7. Page<User> page = new Page<>(current, size);
  8. // 执行分页查询
  9. return userMapper.selectPage(page, null);
  10. }
  11. }

2.4 多数据源适配

针对不同数据库的分页SQL差异,插件支持自动适配:

  1. // Oracle分页配置示例
  2. @Bean
  3. public MybatisPlusInterceptor oracleInterceptor() {
  4. PaginationInnerInterceptor interceptor = new PaginationInnerInterceptor(DbType.ORACLE);
  5. interceptor.setMaxLimit(2000L); // 设置最大分页数
  6. return new MybatisPlusInterceptor().addInnerInterceptor(interceptor);
  7. }

三、条件查询构造器详解

3.1 基础条件查询

Wrapper接口体系包含:

  • QueryWrapper:普通条件查询
  • LambdaQueryWrapper:Lambda表达式查询
  • UpdateWrapper:更新条件构造
  1. // 查询年龄大于25且姓名包含"张"的用户
  2. LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
  3. wrapper.gt(User::getAge, 25)
  4. .like(User::getName, "张");
  5. List<User> users = userMapper.selectList(wrapper);

3.2 复杂条件组合

支持嵌套查询和逻辑运算:

  1. // 查询(年龄<20或工资>5000)且部门为"研发部"的用户
  2. QueryWrapper<User> wrapper = new QueryWrapper<>();
  3. wrapper.nested("age < 20 or salary > 5000")
  4. .eq("dept", "研发部");

3.3 常用条件方法

方法名 说明 示例
eq() 等于 wrapper.eq(“name”, “张三”)
ne() 不等于 wrapper.ne(“status”, 0)
between() 区间范围 wrapper.between(“age”, 20,30)
in() IN查询 wrapper.in(“id”, ids)
orderByAsc() 升序排序 wrapper.orderByAsc(“create_time”)

四、SQL打印与性能分析

4.1 基础日志配置

在application.yml中配置:

  1. mybatis-plus:
  2. configuration:
  3. log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

4.2 性能分析插件

配置SQL执行分析器:

  1. @Bean
  2. public MybatisPlusInterceptor performanceInterceptor() {
  3. return new MybatisPlusInterceptor().addInnerInterceptor(
  4. new IllegalSQLInnerInterceptor() // 非法SQL拦截
  5. .addSqlParserFilter(metaObject -> {
  6. // 排除特定表
  7. String tableName = metaObject.getTableInfo().getTableName();
  8. return !"sys_log".equals(tableName);
  9. })
  10. );
  11. }

4.3 P6Spy日志增强(推荐)

  1. 添加依赖:

    1. <dependency>
    2. <groupId>p6spy</groupId>
    3. <artifactId>p6spy</artifactId>
    4. <version>3.9.1</version>
    5. </dependency>
  2. 修改配置:

    1. spring:
    2. datasource:
    3. url: jdbc:p6spy:mysql://localhost:3306/test
    4. driver-class-name: com.p6spy.engine.spy.P6SpyDriver
  3. 自定义spy.properties:

    1. # 日志格式配置
    2. logMessageFormat=com.p6spy.engine.spy.appender.CustomLineFormat
    3. customLogMessageFormat=%(currentTime)|%(executionTime)|%(category)|connection%(connectionId)|%(sqlSingleLine)

五、高级应用场景

5.1 动态表名处理

实现TableNameHandler接口:

  1. public class DynamicTableNameHandler implements TableNameHandler {
  2. @Override
  3. public String dynamicTableName(String sql, String tableName) {
  4. // 根据分表策略返回实际表名
  5. return tableName + "_" + (System.currentTimeMillis() % 4);
  6. }
  7. }

5.2 多租户SQL拦截

通过InnerInterceptor实现租户隔离:

  1. @Bean
  2. public MybatisPlusInterceptor tenantInterceptor() {
  3. TenantLineInnerInterceptor interceptor = new TenantLineInnerInterceptor(
  4. new TenantLineHandler() {
  5. @Override
  6. public Expression getTenantId() {
  7. return new LongValue(1L); // 硬编码租户ID
  8. }
  9. @Override
  10. public String getTenantIdColumn() {
  11. return "tenant_id";
  12. }
  13. }
  14. );
  15. return new MybatisPlusInterceptor().addInnerInterceptor(interceptor);
  16. }

六、最佳实践建议

  1. 分页参数校验

    1. public IPage<User> safeQuery(Long current, Long size) {
    2. if (current == null || current < 1) current = 1;
    3. if (size == null || size > 100) size = 10; // 限制最大分页数
    4. return userMapper.selectPage(new Page<>(current, size), null);
    5. }
  2. 复杂查询优化

  • 避免在Wrapper中使用过多OR条件
  • 大数据量分页使用selectPageoptimizeJoin参数
  • 定期清理分页插件的缓存
  1. SQL日志管理
  • 生产环境建议使用P6Spy而非StdOutImpl
  • 设置合理的日志级别(建议WARN以上)
  • 对敏感数据表进行脱敏处理

七、常见问题解决方案

7.1 分页总数不准确

问题原因:多表关联时COUNT(*)计算错误
解决方案:

  1. // 自定义COUNT查询
  2. Page<User> page = new Page<>(1, 10);
  3. page.setOptimizeJoin(true); // 开启优化
  4. IPage<User> result = userMapper.selectMapsPage(page, wrapper);

7.2 条件查询失效

典型场景:

  1. // 错误示例:条件方法调用顺序错误
  2. wrapper.orderByAsc("id").eq("status", 1); // orderBy会覆盖之前的条件
  3. // 正确写法
  4. wrapper.eq("status", 1).orderByAsc("id");

7.3 SQL日志不输出

排查步骤:

  1. 检查日志框架配置(Logback/Log4j2)
  2. 确认MyBatis日志级别设置为DEBUG
  3. 检查是否被其他拦截器覆盖

八、版本兼容性说明

MyBatis-Plus版本 SpringBoot版本 适配说明
3.5.x 2.7.x 推荐生产环境使用
3.4.x 2.5.x 长期支持版本
3.3.x 2.3.x 仅建议旧项目维护使用

注:使用SpringBoot 3.x需等待MyBatis-Plus 4.0正式发布

九、总结与展望

MyBatis-Plus通过分页插件、条件构造器和SQL分析三大核心功能,显著提升了CRUD操作的开发效率。在实际项目中,建议:

  1. 中小型项目可直接使用标准配置
  2. 大型分布式系统需结合动态表名和多租户功能
  3. 性能敏感场景应启用P6Spy进行深度优化

未来版本可能增加AI驱动的SQL优化建议功能,值得持续关注。开发者应定期查阅官方文档更新日志,掌握最新特性。

相关文章推荐

发表评论