Spring Boot3.5与Mybatis-Plus整合开发实战指南
1. 项目概述为什么选择Spring Boot3.5与Mybatis-Plus组合在Java企业级应用开发领域Spring Boot3.5和Mybatis-Plus的组合已经成为技术选型的热门选择。Spring Boot3.5作为Spring框架的最新稳定版本带来了对Java17的全面支持、GraalVM原生镜像编译能力以及更强大的性能优化。而Mybatis-Plus作为Mybatis的增强工具在保留Mybatis所有特性的基础上提供了自动CRUD、强大的条件构造器、分页插件等开箱即用的功能。这个组合特别适合需要快速迭代的中大型项目。我最近在一个电商后台系统中采用这个技术栈原本需要2周完成的用户模块CRUD接口借助Mybatis-Plus的代码生成器和Spring Boot的自动配置3天就完成了基础功能开发。更重要的是这种组合不会牺牲灵活性——当遇到复杂SQL查询时你仍然可以回归到原生Mybatis的XML映射方式。2. 环境准备与项目初始化2.1 基础环境配置在开始整合前需要确保开发环境满足以下要求JDK17或更高版本Spring Boot3.x的最低要求Maven3.6或Gradle7.xIDE推荐IntelliJ IDEA 2023.x数据库准备MySQL8.x或PostgreSQL15.x注意Spring Boot3.x不再支持JDK8如果你必须使用JDK8只能选择Spring Boot2.7.x版本。2.2 创建Spring Boot项目使用Spring Initializr创建项目时需要选择以下依赖Spring Web用于构建Web接口Lombok简化实体类编写MySQL Driver或其他数据库驱动对于Mybatis-Plus我们需要手动添加依赖。在pom.xml中添加dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.2/version /dependency3. 核心整合步骤详解3.1 数据源配置在application.yml中配置数据源是第一步spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/your_db?useSSLfalseserverTimezoneUTC username: root password: yourpasswordMybatis-Plus的配置项通常以mybatis-plus开头mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 开启SQL日志 global-config: db-config: id-type: auto # 主键策略 logic-delete-field: deleted # 逻辑删除字段 logic-delete-value: 1 # 已删除值 logic-not-delete-value: 0 # 未删除值3.2 实体类与Mapper接口使用Mybatis-Plus时实体类需要添加注解Data TableName(sys_user) // 指定表名 public class User { TableId(type IdType.AUTO) // 主键自增 private Long id; private String username; private String password; TableField(fill FieldFill.INSERT) // 自动填充 private LocalDateTime createTime; TableLogic // 逻辑删除标记 private Integer deleted; }Mapper接口只需要继承BaseMapper即可获得CRUD方法public interface UserMapper extends BaseMapperUser { // 自定义方法 Select(SELECT * FROM sys_user WHERE username #{name}) User selectByName(Param(name) String username); }3.3 Service层实现Mybatis-Plus提供了IService接口和ServiceImpl实现类public interface UserService extends IServiceUser { // 自定义业务方法 User getUserWithRoles(Long id); } Service public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService { Override public User getUserWithRoles(Long id) { // 复杂业务逻辑实现 } }4. 高级特性与实战技巧4.1 条件构造器的灵活使用Mybatis-Plus的QueryWrapper和LambdaQueryWrapper可以构建复杂查询// 查询年龄大于18且姓张的用户 LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.gt(User::getAge, 18) .likeRight(User::getUsername, 张) .orderByDesc(User::getCreateTime); ListUser users userMapper.selectList(wrapper);4.2 分页插件配置与使用首先需要配置分页插件Configuration public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); return interceptor; } }使用分页查询PageUser page new Page(1, 10); // 当前页每页大小 LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.eq(User::getStatus, 1); PageUser result userMapper.selectPage(page, wrapper);4.3 自动填充功能实现实现MetaObjectHandler接口来处理自动填充Component public class MyMetaObjectHandler implements MetaObjectHandler { Override public void insertFill(MetaObject metaObject) { this.strictInsertFill(metaObject, createTime, LocalDateTime.class, LocalDateTime.now()); this.strictInsertFill(metaObject, updateTime, LocalDateTime.class, LocalDateTime.now()); } Override public void updateFill(MetaObject metaObject) { this.strictUpdateFill(metaObject, updateTime, LocalDateTime.class, LocalDateTime.now()); } }5. 常见问题与解决方案5.1 类型处理器问题当使用Java8的新时间APILocalDateTime等时需要确保Mybatis-Plus的版本支持mybatis-plus: configuration: default-enum-type-handler: org.apache.ibatis.type.EnumOrdinalTypeHandler map-underscore-to-camel-case: true log-impl: org.apache.ibatis.logging.stdout.StdOutImpl5.2 多数据源配置在需要连接多个数据库的场景下可以使用dynamic-datasource-spring-boot-starterConfiguration MapperScan(basePackages com.example.mapper) public class DataSourceConfig { Bean ConfigurationProperties(spring.datasource.master) public DataSource masterDataSource() { return DataSourceBuilder.create().build(); } Bean ConfigurationProperties(spring.datasource.slave) public DataSource slaveDataSource() { return DataSourceBuilder.create().build(); } Bean public DataSource dynamicDataSource() { MapObject, Object dataSourceMap new HashMap(); dataSourceMap.put(master, masterDataSource()); dataSourceMap.put(slave, slaveDataSource()); DynamicDataSource dynamicDataSource new DynamicDataSource(); dynamicDataSource.setTargetDataSources(dataSourceMap); dynamicDataSource.setDefaultTargetDataSource(masterDataSource()); return dynamicDataSource; } }5.3 性能优化建议批量操作使用executeBatchListUser userList new ArrayList(); // 添加数据... userService.saveBatch(userList, 1000); // 每1000条提交一次复杂查询使用原生SQLSelect(SELECT u.*, r.role_name FROM sys_user u LEFT JOIN sys_user_role ur ON u.id ur.user_id LEFT JOIN sys_role r ON ur.role_id r.id WHERE u.id #{userId}) User selectUserWithRole(Param(userId) Long userId);合理使用二级缓存mybatis-plus: configuration: cache-enabled: true6. 最佳实践与架构建议在实际项目中我总结出以下几点经验分层清晰Controller只处理HTTP请求和响应业务逻辑放在Service层复杂SQL放在Mapper层使用DTO进行数据传输避免直接暴露实体类给前端统一异常处理使用ControllerAdvice处理Mybatis-Plus和业务异常接口文档化整合Swagger或Knife4j自动生成API文档监控与性能分析整合Prometheus和Grafana监控SQL性能测试策略单元测试测试Service层方法集成测试测试Controller接口SQL测试验证复杂SQL的正确性SpringBootTest public class UserServiceTest { Autowired private UserService userService; Test public void testGetUserWithRoles() { User user userService.getUserWithRoles(1L); Assert.notNull(user, 用户查询失败); Assert.notEmpty(user.getRoles(), 用户角色为空); } }在项目后期随着业务复杂度的增加可以考虑引入Mybatis-Plus的租户插件、数据权限插件等高级功能但这些需要根据实际业务需求谨慎评估。