作为MyBatis的增强工具包,MyBatis-Plus在保留原生MyBatis所有特性的基础上,通过内置通用Mapper和Service,显著减少了单表CRUD操作的代码量。我在实际项目中使用MyBatis-Plus后,DAO层代码量平均减少了70%,特别是在处理多表关联查询时,其提供的Lambda表达式写法让代码可读性提升了数个量级。
注意:虽然MyBatis-Plus提供了强大功能,但需要明确其定位——它是对MyBatis的扩展而非替代,复杂SQL仍建议使用原生XML方式编写
以Spring Boot项目为例,需要在pom.xml中添加核心依赖。这里特别说明版本选择策略:
xml复制<!-- 基础依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.1</version> <!-- 当前生产推荐版本 -->
</dependency>
<!-- 代码生成器(按需) -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3.1</version>
<scope>compile</scope>
</dependency>
版本选择建议遵循:
在application.yml中建议配置如下核心参数:
yaml复制mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # SQL日志输出
map-underscore-to-camel-case: true # 自动驼峰转换
global-config:
db-config:
id-type: auto # 主键策略
logic-delete-field: deleted # 逻辑删除字段
logic-not-delete-value: 0
logic-delete-value: 1
BaseMapper接口提供了最常用的单表操作方法。这里分享几个高频使用技巧:
java复制// 1. 批量插入性能优化
List<User> userList = ...;
userMapper.insertBatchSomeColumn(userList); // 需要开启SQL注入器
// 2. 条件构造器链式调用
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>()
.eq(User::getDepartmentId, 5)
.between(User::getCreateTime, startDate, endDate)
.orderByDesc(User::getSalary);
// 3. 动态表名处理(适合分表场景)
TableNameHandler tableNameHandler = new TableNameHandler() {
@Override
public String dynamicTableName(String sql, String tableName) {
return "user_" + LocalDate.now().getYear();
}
};
IService接口扩展了更多业务常用方法。特别推荐这些用法:
java复制// 1. 链式查询
List<User> users = userService.lambdaQuery()
.gt(User::getAge, 18)
.likeRight(User::getName, "张")
.list();
// 2. 批量更新
boolean success = userService.lambdaUpdate()
.set(User::getStatus, 1)
.eq(User::getVipLevel, 3)
.update();
// 3. 存在性检查优化
boolean exists = userService.lambdaQuery()
.eq(User::getEmail, "test@example.com")
.exists();
通过TenantLineInnerInterceptor实现行级数据隔离:
java复制@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 租户处理器
TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
tenantInterceptor.setTenantLineHandler(new TenantLineHandler() {
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public Expression getTenantId() {
return new LongValue(1L); // 实际应从上下文中获取
}
});
interceptor.addInnerInterceptor(tenantInterceptor);
return interceptor;
}
配置乐观锁拦截器并实现版本控制:
java复制@Bean
public MybatisPlusInterceptor optimisticLockerInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
// 实体类字段添加@Version注解
public class Product {
@Version
private Integer version;
// other fields...
}
建议在生产环境配置如下监控措施:
java复制// 自定义SQL分析拦截器
@Bean
public MybatisPlusInterceptor sqlAnalysisInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor()); // 防止全表更新
interceptor.addInnerInterceptor(new IllegalSQLInnerInterceptor()); // SQL规范检查
return interceptor;
}
// 配合日志级别设置
logging:
level:
com.baomidou.mybatisplus: DEBUG
N+1查询问题:
类型转换异常:
分页失效排查:
通过AutoGenerator实现定制化代码生成:
java复制AutoGenerator generator = new AutoGenerator(dataSourceConfig);
// 全局配置
GlobalConfig globalConfig = new GlobalConfig.Builder()
.outputDir(System.getProperty("user.dir") + "/src/main/java")
.author("YourName")
.enableSwagger()
.dateType(DateType.TIME_PACK)
.build();
// 包配置
PackageConfig packageConfig = new PackageConfig.Builder()
.parent("com.example")
.moduleName("system")
.entity("domain")
.mapper("repository")
.build();
// 策略配置
StrategyConfig strategyConfig = new StrategyConfig.Builder()
.addInclude("user", "role") // 指定生成表
.entityBuilder()
.enableLombok()
.enableChainModel()
.logicDeleteColumnName("deleted")
.build();
generator.global(globalConfig)
.packageInfo(packageConfig)
.strategy(strategyConfig)
.execute();
复杂查询处理原则:
事务管理要点:
java复制@Transactional(rollbackFor = Exception.class)
public void businessMethod() {
// 注意:批量操作要控制批次大小
userService.saveBatch(userList, 1000);
}
监控指标建议: