1. 为什么选择Spring Boot 3 + MyBatis-Plus 3.5.9组合?
在2023年的Java后端开发生态中,这套技术组合正在成为企业级应用的新基准配置。Spring Boot 3基于Spring Framework 6构建,全面拥抱Java 17+的特性,而MyBatis-Plus 3.5.9作为MyBatis最强大的增强工具,提供了连作者都惊叹的开发效率提升。
我最近在电商中台项目中采用这套组合时,单日完成了17个CRUD接口的开发,这得益于两个框架的深度契合。Spring Boot 3的自动配置机制与MyBatis-Plus的智能代码生成器配合,让基础开发工作量减少了约60%。特别是在处理分页查询时,原本需要手动编写的PageHelper配置,现在只需要在yaml中添加两行配置即可。
注意:MyBatis-Plus 3.5.9是最后一个全面兼容Spring Boot 2.x和3.x的版本,后续版本将仅支持Spring Boot 3.x
2. 环境搭建与项目初始化
2.1 基础环境准备
推荐使用以下环境组合,这是经过多个生产项目验证的稳定配置:
- JDK 17(必须,Spring Boot 3的最低要求)
- Maven 3.8+(建议使用阿里云镜像)
- IntelliJ IDEA 2023.1+(对Java 17语法支持最完善)
在pom.xml中需要特别注意的依赖项:
xml复制<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.9</version>
<scope>compile</scope>
</dependency>
2.2 自动生成器配置技巧
MyBatis-Plus的代码生成器是效率提升的关键。这个配置模板是我在金融项目中优化过的版本:
java复制FastAutoGenerator.create("jdbc:mysql://localhost:3306/your_db", "root", "password")
.globalConfig(builder -> {
builder.author("yourname")
.outputDir(System.getProperty("user.dir") + "/src/main/java")
.enableSwagger() // 集成springdoc-openapi
.dateType(DateType.TIME_PACK)
.commentDate("yyyy-MM-dd");
})
.packageConfig(builder -> {
builder.parent("com.your.package")
.entity("entity")
.service("service")
.serviceImpl("service.impl")
.mapper("mapper")
.xml("mapper.xml")
.controller("controller");
})
.strategyConfig(builder -> {
builder.addInclude("tbl_user","tbl_order") // 表名
.addTablePrefix("tbl_")
.entityBuilder()
.enableLombok()
.enableChainModel()
.controllerBuilder()
.enableRestStyle();
})
.templateEngine(new FreemarkerTemplateEngine())
.execute();
实战经验:生成实体类时一定要启用enableChainModel(),这会让你的Service层写法变得异常简洁
3. 核心功能深度解析
3.1 分页查询的现代化实现
MyBatis-Plus 3.5.9的分页插件有了重大改进,现在支持更灵活的配置方式。这是我在物流系统中使用的配置方案:
yaml复制mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
logic-delete-field: deleted # 全局逻辑删除字段
logic-not-delete-value: 0
logic-delete-value: 1
mapper-locations: classpath*:/mapper/**/*.xml
分页接口的现代写法示例:
java复制@GetMapping("/users")
public R<Page<UserVO>> getUserPage(
@RequestParam(defaultValue = "1") Integer current,
@RequestParam(defaultValue = "10") Integer size,
@RequestParam(required = false) String username) {
LambdaQueryWrapper<User> wrapper = Wrappers.lambdaQuery();
wrapper.like(StringUtils.isNotBlank(username), User::getUsername, username);
Page<User> page = userService.page(new Page<>(current, size), wrapper);
return R.success(page.convert(user -> convertToVO(user)));
}
3.2 枚举处理的进阶技巧
MyBatis-Plus 3.5.9对枚举的支持达到了新高度。处理订单状态枚举时,可以这样定义:
java复制@Getter
public enum OrderStatus {
UNPAID(0, "未支付"),
PAID(1, "已支付"),
DELIVERED(2, "已发货"),
COMPLETED(3, "已完成"),
CANCELLED(4, "已取消");
private final int code;
private final String desc;
@JsonCreator
public static OrderStatus fromCode(Integer code) {
return Arrays.stream(values())
.filter(v -> v.code == code)
.findFirst()
.orElse(null);
}
}
在实体类中使用:
java复制@TableName("tbl_order")
public class Order {
@TableId(type = IdType.AUTO)
private Long id;
@EnumValue
private OrderStatus status;
@TableField(typeHandler = JacksonTypeHandler.class)
private List<String> tags;
}
避坑指南:枚举字段必须同时添加@EnumValue注解和自定义的@JsonCreator方法,才能完美支持前后端交互
4. 生产环境实战经验
4.1 多数据源配置方案
在微服务架构中,有时仍需访问多个数据源。这是经过线上验证的可靠配置:
java复制@Configuration
@MapperScan(basePackages = "com.primary.mapper", sqlSessionTemplateRef = "primarySqlSessionTemplate")
public class PrimaryDataSourceConfig {
@Bean
@ConfigurationProperties("spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean
public SqlSessionFactory primarySqlSessionFactory(
@Qualifier("primaryDataSource") DataSource dataSource) throws Exception {
MybatisSqlSessionFactoryBean factory = new MybatisSqlSessionFactoryBean();
factory.setDataSource(dataSource);
factory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources("classpath:mapper/primary/*.xml"));
factory.setPlugins(new Interceptor[]{
new PaginationInnerInterceptor(DbType.MYSQL)
});
return factory.getObject();
}
// 类似配置secondary数据源...
}
4.2 性能优化关键点
在高并发场景下,这些配置能显著提升性能:
- 连接池配置(以HikariCP为例):
yaml复制spring:
datasource:
hikari:
maximum-pool-size: 20
minimum-idle: 5
connection-timeout: 30000
idle-timeout: 600000
max-lifetime: 1800000
- MyBatis二级缓存配置:
java复制@Configuration
public class MyBatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 分页插件
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
// 乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
// 防止全表更新与删除
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
@Bean
public ConfigurationCustomizer configurationCustomizer() {
return configuration -> {
configuration.setCacheEnabled(true);
configuration.setLazyLoadingEnabled(false);
configuration.setAggressiveLazyLoading(false);
};
}
}
5. 常见问题解决方案
5.1 与SpringDoc的集成问题
Spring Boot 3推荐使用springdoc-openapi替代传统的Swagger。集成时需要注意:
java复制@Configuration
public class SpringDocConfig {
@Bean
public OpenAPI springShopOpenAPI() {
return new OpenAPI()
.info(new Info().title("API文档")
.description("Spring Boot 3 + MyBatis-Plus 3.5.9项目")
.version("v1.0")
.license(new License().name("Apache 2.0")))
.externalDocs(new ExternalDocumentation()
.description("MyBatis-Plus文档")
.url("https://baomidou.com"));
}
}
5.2 复杂查询的Lambda写法
当遇到多表关联查询时,可以这样构建查询条件:
java复制public Page<UserOrderDTO> getUserOrderPage(PageQuery query) {
return userMapper.selectUserOrderPage(new Page<>(query.getPage(), query.getSize()),
Wrappers.lambdaQuery(User.class)
.like(StringUtils.isNotBlank(query.getKeyword()), User::getName, query.getKeyword())
.in(User::getStatus, Arrays.asList(1, 2))
.orderByDesc(User::getCreateTime));
}
对应的XML映射文件:
xml复制<select id="selectUserOrderPage" resultType="com.example.dto.UserOrderDTO">
SELECT u.*, o.order_no, o.amount
FROM user u LEFT JOIN order o ON u.id = o.user_id
${ew.customSqlSegment}
</select>
在微服务项目中,这种写法比传统的Example查询性能提升约30%,特别是在处理分页时效果更明显
