避开这些坑!Spring Boot 3.x整合MyBatis-Plus 3.5.1的配置细节与常见问题排查
避开这些坑Spring Boot 3.x整合MyBatis-Plus 3.5.1的配置细节与常见问题排查Spring Boot 3.x与MyBatis-Plus 3.5.1的整合看似简单但实际开发中版本兼容性、配置细节等问题常常让开发者踩坑。本文将深入剖析那些官方文档没明说、但实际项目必遇的典型问题帮你一次性搞定整合。1. 环境准备中的隐藏陷阱1.1 依赖版本的地雷阵很多教程只告诉你添加mybatis-plus-boot-starter依赖但没提醒这些关键点!-- 典型错误示例直接复制旧版本配置 -- dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.1/version /dependency实际需要关注的细节JDK版本要求Spring Boot 3.x需要JDK17而MyBatis-Plus 3.5.1最低支持JDK8配套依赖版本spring-boot-starter-jdbc必须≥3.0.0mybatis-spring需要≥2.3.0MySQL驱动必须使用mysql-connector-java而非老版的mysql-connector提示用Maven的dependency:tree命令检查依赖冲突特别注意旧项目升级时遗留的HikariCP或Druid版本问题1.2 数据库配置的魔鬼细节YAML配置看着简单但Spring Boot 3.x的这些变化最易出错# 错误配置Spring Boot 2.x写法 spring: datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://localhost:3306/test正确姿势spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver # 必须用cj驱动 url: jdbc:mysql://localhost:3306/test?useSSLfalseserverTimezoneUTC username: root password: 123456 hikari: connection-timeout: 30000 maximum-pool-size: 20常见报错解决方案No suitable driver检查驱动类名和JDBC URL格式The server time zone value...URL后添加serverTimezoneAsia/ShanghaiPublic Key Retrieval is not allowed追加allowPublicKeyRetrievaltrue2. 注解配置的深坑指南2.1 MapperScan的定位玄机新手常犯的错误是把注解放在错误的类上// 错误示例放在Configuration类而非启动类 Configuration MapperScan(com.example.mapper) public class MybatisConfig { ... }正确做法SpringBootApplication MapperScan(com.example.mapper) // 必须放在启动类 public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }为什么重要放在非启动类可能导致Mapper接口未被扫描多模块项目需要指定准确包路径与Repository注解冲突时优先采用MapperScan2.2 实体类注解的隐藏规则MyBatis-Plus的TableName等注解有些非直观行为Data TableName(value t_user, autoResultMap true) // 注意autoResultMap的作用 public class User { TableId(type IdType.AUTO) // 必须显式指定主键策略 private Long id; TableField(value user_name, exist true) // 字段映射配置 private String name; TableField(exist false) // 非表字段必须声明 private String tempField; }易错点警示忘记TableId导致insert报错字段名驼峰转下划线失效时的处理方案枚举类型需要配合EnumValue使用3. 运行时的高频故障3.1 分页插件的神秘失效配置了分页插件但不起作用看看这个典型错误// 错误配置方式 Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); return interceptor; }完整正确配置Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); // 分页插件 PaginationInnerInterceptor paginationInterceptor new PaginationInnerInterceptor(DbType.MYSQL); paginationInterceptor.setMaxLimit(1000L); // 单页最大记录数 interceptor.addInnerInterceptor(paginationInterceptor); // 乐观锁插件按需添加 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } }关键点必须指定DbType类型分页参数必须放在IPage对象中传入注意PageHelper的冲突问题3.2 事务管理的静默失败Spring事务与MyBatis-Plus结合时的常见问题Service public class UserService { Transactional public void batchUpdate(ListUser users) { // 错误循环中单条操作不会回滚 users.forEach(user - updateById(user)); } }正确的事务用法Transactional(rollbackFor Exception.class) public void properBatchUpdate(ListUser users) { // 正确使用MyBatis-Plus的批量方法 updateBatchById(users); // 或者使用Service的saveOrUpdateBatch userService.saveOrUpdateBatch(users); }事务要点备忘确认EnableTransactionManagement已启用检查方法是否为public避免同类自调用导致AOP失效4. 性能调优与高级技巧4.1 SQL日志输出的正确姿势开发阶段查看SQL是基本需求但默认配置可能不显示完整信息# application.yml关键配置 mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 控制台输出 global-config: db-config: table-prefix: t_ # 全局表前缀 id-type: auto # 全局主键策略 banner: false # 关闭启动logo日志增强方案Bean public PerformanceInterceptor performanceInterceptor() { PerformanceInterceptor interceptor new PerformanceInterceptor(); interceptor.setFormat(true); // 格式化SQL输出 interceptor.setMaxTime(1000); // 超过1秒的SQL警告 return interceptor; }4.2 复杂查询的Lambda写法避免SQL注入的同时保持代码可读性// 条件构造器最佳实践 public ListUser queryUsers(String name, Integer minAge) { return lambdaQuery() .eq(StringUtils.isNotBlank(name), User::getName, name) .ge(minAge ! null, User::getAge, minAge) .orderByDesc(User::getCreateTime) .list(); } // 更新操作示例 public void updateEmail(Long userId, String email) { lambdaUpdate() .eq(User::getId, userId) .set(User::getEmail, email) .set(User::getUpdateTime, LocalDateTime.now()) .update(); }复杂查询技巧动态WHERE条件拼接嵌套查询处理自定义SQL与Wrapper结合5. 生产环境必备配置5.1 多数据源整合方案实际项目常需要多数据源典型配置如下Configuration MapperScan(basePackages com.example.mapper.db1, sqlSessionTemplateRef db1SqlSessionTemplate) public class Db1DataSourceConfig { Bean(name db1DataSource) ConfigurationProperties(prefix spring.datasource.db1) public DataSource db1DataSource() { return DataSourceBuilder.create().build(); } Bean(name db1SqlSessionFactory) public SqlSessionFactory db1SqlSessionFactory(Qualifier(db1DataSource) DataSource dataSource) throws Exception { MybatisSqlSessionFactoryBean factory new MybatisSqlSessionFactoryBean(); factory.setDataSource(dataSource); factory.setMapperLocations(new PathMatchingResourcePatternResolver() .getResources(classpath:mapper/db1/*.xml)); return factory.getObject(); } Bean(name db1SqlSessionTemplate) public SqlSessionTemplate db1SqlSessionTemplate( Qualifier(db1SqlSessionFactory) SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }多数据源要点每个数据源独立配置类指定不同的Mapper扫描路径事务管理器需要区分5.2 监控与健康检查生产环境需要添加的健康检查配置management: endpoints: web: exposure: include: health,info,metrics endpoint: health: show-details: always配合MyBatis-Plus的监控Bean public MybatisPlusSqlInjector mybatisPlusSqlInjector() { return new MybatisPlusSqlInjector(); } Bean public PaginationInterceptor paginationInterceptor() { PaginationInterceptor paginationInterceptor new PaginationInterceptor(); paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true)); return paginationInterceptor; }最后提醒升级到Spring Boot 3.x后记得测试所有MyBatis-Plus的CRUD操作特别是批量操作方法因为底层JDBC规范可能有变化。遇到Invalid bound statement错误时优先检查Mapper接口与XML文件的对应关系。