Spring Boot 3.5与MyBatis-Plus整合开发实战指南

📅 2026/7/21 21:35:25
Spring Boot 3.5与MyBatis-Plus整合开发实战指南
1. 为什么选择Spring Boot 3.5与MyBatis-Plus组合在Java企业级应用开发领域Spring Boot 3.5和MyBatis-Plus的组合已经成为许多开发团队的首选技术栈。Spring Boot 3.5作为Spring框架的最新稳定版本带来了对Java 17的全面支持、GraalVM原生镜像编译能力的显著提升以及更完善的响应式编程模型。而MyBatis-Plus作为MyBatis的增强工具在保留MyBatis灵活性的同时通过内置通用Mapper、分页插件、代码生成器等实用功能大幅减少了样板代码的编写。这个组合特别适合需要快速开发但又不想牺牲灵活性的项目。Spring Boot 3.5提供了自动配置、依赖管理等便利而MyBatis-Plus则填补了传统MyBatis在CRUD操作上的重复劳动问题。两者结合既能享受Spring生态的丰富功能又能保持对SQL的精细控制能力。2. 环境准备与项目初始化2.1 创建Spring Boot 3.5项目首先确保你的开发环境满足以下要求JDK 17或更高版本Maven 3.6或Gradle 7.xIDEIntelliJ IDEA或Eclipse使用Spring Initializr创建项目时选择以下依赖Spring WebLombok可选但推荐MySQL Driver或其他数据库驱动对于Maven项目pom.xml中需要添加Spring Boot 3.5的父POMparent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.5.0/version /parent2.2 添加MyBatis-Plus依赖在pom.xml中添加MyBatis-Plus的starter依赖dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3.1/version /dependency注意版本兼容性MyBatis-Plus 3.5.x版本专为Spring Boot 3.x优化不建议在Spring Boot 2.x项目中使用。3. 核心配置详解3.1 数据源配置在application.yml中配置数据源和MyBatis-Plus基本设置spring: datasource: url: jdbc:mysql://localhost:3306/your_db?useSSLfalseserverTimezoneUTC username: root password: yourpassword driver-class-name: com.mysql.cj.jdbc.Driver 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 MyBatis-Plus配置类创建一个配置类来定制MyBatis-Plus行为Configuration MapperScan(com.yourpackage.mapper) public class MybatisPlusConfig { Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor new MybatisPlusInterceptor(); // 添加分页插件 interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL)); // 添加乐观锁插件 interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor()); return interceptor; } }4. 实体与Mapper开发4.1 实体类定义使用Lombok简化实体类代码Data TableName(user) // 指定表名 public class User { TableId(type IdType.AUTO) // 主键自增 private Long id; private String username; private Integer age; TableField(fill FieldFill.INSERT) // 自动填充 private LocalDateTime createTime; TableField(fill FieldFill.INSERT_UPDATE) private LocalDateTime updateTime; TableLogic // 逻辑删除标记 private Integer deleted; }4.2 Mapper接口继承BaseMapper获得CRUD方法public interface UserMapper extends BaseMapperUser { // 自定义方法 Select(SELECT * FROM user WHERE age #{age}) ListUser selectUsersOlderThan(Param(age) Integer age); }MyBatis-Plus的强大之处在于即使不编写任何XML文件UserMapper已经具备了基本的CRUD操作能力。通过继承BaseMapper你自动获得了以下方法insert: 插入一条记录deleteById: 根据主键删除updateById: 根据主键更新selectById: 根据主键查询selectList: 查询所有记录以及更多...5. 服务层与控制器实现5.1 服务层实现Service public class UserServiceImpl extends ServiceImplUserMapper, User implements UserService { public PageUser getUsersByPage(int pageNum, int pageSize) { PageUser page new Page(pageNum, pageSize); return baseMapper.selectPage(page, null); } Transactional public boolean updateUserAge(Long id, Integer newAge) { User user getById(id); if (user null) { return false; } user.setAge(newAge); return updateById(user); } }5.2 控制器示例RestController RequestMapping(/users) public class UserController { Autowired private UserService userService; GetMapping(/{id}) public ResultUser getUser(PathVariable Long id) { User user userService.getById(id); return Result.success(user); } GetMapping(/page) public ResultPageUser getUsersByPage( RequestParam(defaultValue 1) int pageNum, RequestParam(defaultValue 10) int pageSize) { return Result.success(userService.getUsersByPage(pageNum, pageSize)); } }6. 高级特性与实战技巧6.1 条件构造器使用MyBatis-Plus的Wrapper提供了强大的查询条件构造能力// 查询年龄大于18且用户名包含admin的用户 LambdaQueryWrapperUser wrapper new LambdaQueryWrapper(); wrapper.gt(User::getAge, 18) .like(User::getUsername, admin) .orderByDesc(User::getCreateTime); ListUser users userMapper.selectList(wrapper);6.2 自动填充功能实现实现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()); } }6.3 多数据源配置对于需要连接多个数据库的场景Configuration MapperScan(basePackages com.yourpackage.mapper.db1, sqlSessionTemplateRef db1SqlSessionTemplate) public class Db1DataSourceConfig { Bean ConfigurationProperties(prefix spring.datasource.db1) public DataSource db1DataSource() { return DataSourceBuilder.create().build(); } Bean public SqlSessionFactory db1SqlSessionFactory(Qualifier(db1DataSource) DataSource dataSource) throws Exception { MybatisSqlSessionFactoryBean factoryBean new MybatisSqlSessionFactoryBean(); factoryBean.setDataSource(dataSource); return factoryBean.getObject(); } Bean public SqlSessionTemplate db1SqlSessionTemplate(Qualifier(db1SqlSessionFactory) SqlSessionFactory sqlSessionFactory) { return new SqlSessionTemplate(sqlSessionFactory); } }7. 常见问题与解决方案7.1 分页插件不生效可能原因及解决方案未在配置类中添加分页插件 - 确保已按照3.2节配置分页参数传递不正确 - 前端需正确传递current和size参数使用了自定义SQL但未保持参数一致 - 自定义SQL方法参数需包含Page对象7.2 逻辑删除失效检查要点实体类字段是否添加TableLogic注解全局配置中的逻辑删除字段名是否与实体类一致数据库表是否有对应的逻辑删除字段7.3 性能优化建议批量操作使用saveBatch、updateBatchById等方法替代循环单条操作延迟加载对于关联查询考虑使用TableField(exist false)和单独查询SQL监控启用mybatis-plus.configuration.log-impl查看执行SQL8. 项目实战中的经验分享在实际项目中使用Spring Boot 3.5整合MyBatis-Plus时有几个关键点值得特别注意枚举处理MyBatis-Plus对枚举类型的处理非常友好。可以通过实现IEnum接口或使用EnumValue注解来优雅地处理数据库中的枚举值public enum GenderEnum implements IEnumInteger { MALE(1, 男), FEMALE(2, 女); EnumValue private final int code; private final String desc; // 构造方法、getter等 }多租户实现对于SaaS应用可以利用MyBatis-Plus的多租户插件轻松实现数据隔离public class TenantInterceptor implements InnerInterceptor { Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { // 添加租户条件 } }动态表名对于分表场景可以实现动态表名处理器public class DynamicTableNameParser implements TableNameHandler { Override public String dynamicTableName(String sql, String tableName) { // 根据业务逻辑返回实际表名 return getActualTableName(tableName); } }SQL注入器对于需要扩展通用方法的场景可以自定义SQL注入器public class MySqlInjector extends DefaultSqlInjector { Override public ListAbstractMethod getMethodList(Class? mapperClass) { ListAbstractMethod methodList super.getMethodList(mapperClass); methodList.add(new InsertBatchSomeColumn()); // 添加批量插入方法 return methodList; } }与Spring Boot 3.5新特性结合利用Spring Boot 3.5的GraalVM原生镜像支持可以显著提升应用启动速度。在整合MyBatis-Plus时需要特别注意反射配置# 在resources/META-INF/native-image下添加reflect-config.json [ { name: com.yourpackage.entity.User, allDeclaredFields: true, allDeclaredMethods: true } ]