1. MyBatis-Plus核心功能全景解析
作为Java开发者最常用的ORM框架之一,MyBatis-Plus在传统MyBatis基础上进行了全方位增强。我在多个企业级项目中深度使用该框架后,发现其核心价值主要体现在六个方面:代码生成、条件构造、分页处理、AR模式、性能优化和扩展机制。下面结合具体案例,拆解每个功能的实现原理和最佳实践。
1.1 代码生成器(AutoGenerator)
开发效率提升利器,通过解析数据库表结构自动生成Entity、Mapper、Service、Controller层代码。核心配置示例:
java复制AutoGenerator generator = new AutoGenerator();
generator.setDataSource(new DataSourceConfig
.Builder("jdbc:mysql://localhost:3306/db", "root", "123456")
.build());
generator.setGlobalConfig(new GlobalConfig.Builder()
.outputDir(System.getProperty("user.dir") + "/src/main/java")
.author("developer")
.build());
generator.setPackageConfig(new PackageConfig.Builder()
.parent("com.example")
.moduleName("system")
.build());
关键技巧:通过
StrategyConfig可以自定义命名规则、字段映射策略。建议开启Lombok支持并配置@TableField注解的自动填充策略。
1.2 条件构造器(Wrapper)
动态SQL构建的核心组件,提供三种典型用法:
- QueryWrapper:基础条件构造
java复制wrapper.select("id", "name")
.eq("status", 1)
.between("create_time", startDate, endDate)
.orderByDesc("id");
- LambdaWrapper:类型安全写法
java复制lambdaWrapper.eq(User::getAge, 18)
.likeRight(User::getName, "张");
- UpdateWrapper:更新条件构造
java复制updateWrapper.set("login_count", 0)
.eq("last_login_time", null);
避坑指南:避免在循环中拼接Wrapper条件,每次
eq()/ne()都会创建新的条件实例,可能引发内存问题。
1.3 分页插件(PaginationInterceptor)
企业级应用必备功能,需先注册插件:
java复制@Bean
public MybatisPlusInterceptor paginationInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
分页查询示例:
java复制Page<User> page = new Page<>(1, 10);
userMapper.selectPage(page, queryWrapper);
System.out.println("总记录数:" + page.getTotal());
性能优化:当
page.setSearchCount(false)时跳过count查询,大数据量场景可提升30%+性能。
1.4 主动记录模式(ActiveRecord)
实体类继承Model后获得数据库操作能力:
java复制@TableName("sys_user")
public class User extends Model<User> {
// 字段定义...
}
// 直接操作实体
new User().setName("test").insert();
User user = new User().selectById(1L);
适用场景:适合简单CRUD操作,复杂业务建议仍使用Mapper层。
1.5 性能分析插件(PerformanceInterceptor)
开发阶段监控SQL性能:
yaml复制mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
配置阈值警告:
java复制@Bean
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor interceptor = new PerformanceInterceptor();
interceptor.setMaxTime(1000); // 超过1秒警告
interceptor.setFormat(true);
return interceptor;
}
1.6 数据权限实践(InnerInterceptor)
通过自定义拦截器实现行级数据过滤:
java复制public class DataPermissionInterceptor implements InnerInterceptor {
@Override
public void beforeQuery(Executor executor, MappedStatement ms,
Object parameter, RowBounds rowBounds, ResultHandler resultHandler,
BoundSql boundSql) {
// 追加权限过滤条件
String sql = boundSql.getSql();
String newSql = sql + " AND dept_id IN (" + getPermittedDepts() + ")";
resetSql(ms, boundSql, newSql);
}
}
2. 高级特性深度应用
2.1 多租户方案实现
基于TenantLineInnerInterceptor的SAAS系统解决方案:
java复制interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(
new TenantLineHandler() {
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public Expression getTenantId() {
return new StringValue("当前租户ID");
}
}
));
2.2 逻辑删除最佳实践
全局配置逻辑删除字段:
yaml复制mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted # 字段名
logic-delete-value: 1 # 删除值
logic-not-delete-value: 0 # 未删除值
注意:查询会自动过滤已删除数据,如需包含需手动添加
@InterceptorIgnore注解。
2.3 枚举类型处理
两种推荐处理方式:
- 通用枚举接口:
java复制@Getter
public enum StatusEnum implements IEnum<Integer> {
ENABLED(1), DISABLED(0);
private final int value;
}
- 注解方式:
java复制@EnumValue
private final int code;
3. 生产环境问题排查
3.1 SQL注入防护
避免直接拼接SQL片段:
java复制// 错误示范
wrapper.apply("date_format(create_time,'%Y-%m') = '2023-01'");
// 正确做法
wrapper.apply("date_format(create_time,'%Y-%m') = {0}", "2023-01");
3.2 批量操作优化
使用executeBatch提升性能:
java复制SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH);
UserMapper mapper = session.getMapper(UserMapper.class);
for (int i = 0; i < 1000; i++) {
mapper.insert(new User(...));
if(i % 200 == 0) {
session.flushStatements();
}
}
session.commit();
3.3 字段类型映射
处理JSON类型字段:
java复制@TableField(typeHandler = FastjsonTypeHandler.class)
private List<String> tags;
4. 扩展开发指南
4.1 自定义ID生成器
实现IdentifierGenerator接口:
java复制public class CustomIdGenerator implements IdentifierGenerator {
@Override
public Number nextId(Object entity) {
// 实现雪花算法等分布式ID生成
}
}
4.2 动态表名处理
实现TableNameHandler接口:
java复制public class MonthTableNameHandler implements TableNameHandler {
@Override
public String dynamicTableName(String sql, String tableName) {
return tableName + "_" + LocalDate.now().getMonthValue();
}
}
4.3 审计字段自动填充
配置元对象处理器:
java复制@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createBy", String.class, getCurrentUser());
}
}
在真实项目落地时,建议根据团队技术栈选择适当的功能组合。对于新项目,可以从代码生成+Wrapper+分页这个黄金组合开始,逐步引入更高级特性。特别注意在微服务环境下,要合理配置连接池参数与MyBatis-Plus的全局配置。
