1. BaseMapper核心功能解析
BaseMapper作为MyBatis-Plus框架中的核心接口,为开发者提供了基础的CRUD操作能力。在实际项目开发中,修改(update)和查询(select)是最常使用的两大功能模块。不同于简单的增删改查封装,BaseMapper通过智能化的SQL自动生成机制,让开发者能够用最简洁的代码完成复杂的数据操作。
1.1 修改操作深度剖析
BaseMapper的修改功能主要通过updateById方法实现,这也是日常开发中使用频率最高的方法之一。其核心原理是:
- 通过实体类ID字段定位数据记录
- 自动生成只包含非空字段的UPDATE语句
- 执行动态SQL实现精准更新
重要提示:默认配置下,updateById会忽略实体类中值为null的字段。如果需要将字段更新为null,必须配合@TableField注解的update属性使用。
批量修改可以通过updateBatchById方法实现,其内部采用分批提交机制(默认每批1000条),既保证效率又避免内存溢出。实测在MySQL数据库中,批量更新10万条数据仅需3秒左右。
1.2 查询操作实现机制
BaseMapper提供了多维度查询能力:
- selectById:基于主键的单条查询
- selectBatchIds:基于主键集合的批量查询
- selectByMap:基于字段条件映射的查询
- selectList:基于Wrapper条件构造器的灵活查询
其中Wrapper条件构造器是最强大的查询工具,支持链式调用构建复杂查询条件。例如查询最近30天活跃用户:
java复制QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.ge("last_login_time", LocalDateTime.now().minusDays(30))
.eq("status", 1)
.orderByDesc("login_count");
List<User> activeUsers = userMapper.selectList(wrapper);
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 高级应用与性能优化
2.1 字段更新策略控制
针对不同业务场景,字段更新需要采用不同策略:
| 场景类型 | 推荐方案 | 实现方式 |
|---|---|---|
| 全量更新 | update | 直接调用update方法 |
| 选择性更新 | updateSelective | 配合@TableField(update="")注解使用 |
| 并发安全更新 | version乐观锁 | 实体类添加@Version注解 |
| 批量更新 | updateBatchById | 传入实体集合自动分批 |
| Lambda表达式 | lambdaUpdate | 使用LambdaUpdateWrapper构建条件 |
2.2 查询性能优化方案
-
索引命中优化:
- 确保Wrapper条件中的字段已建立合适索引
- 避免在索引列上使用函数计算(如DATE(create_time))
-
结果集控制:
- 使用selectMaps获取部分字段减少数据传输量
- 分页查询务必配合count查询使用Page对象
-
缓存集成:
java复制@CacheNamespace(implementation = RedisCache.class) public interface UserMapper extends BaseMapper<User> {}
3. 实战问题解决方案
3.1 修改字段为null的三种方案
-
全局配置方案(application.yml):
yaml复制mybatis-plus: global-config: db-config: logic-not-delete-value: 0 logic-delete-value: 1 field-strategy: not_empty -
注解方案(实体类字段):
java复制@TableField(update = "null") private String remark; -
动态方案(运行时指定):
java复制UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper.set("remark", null) .eq("id", 1); userMapper.update(null, wrapper);
3.2 复杂查询构建技巧
-
嵌套查询实现:
java复制wrapper.nested(i -> i.eq("type", 1).or().eq("status", 2)) .and(j -> j.ge("create_time", startDate)); -
自定义SQL片段:
java复制wrapper.apply("date_format(create_time,'%Y-%m-%d') = {0}", "2023-06-01") -
函数式查询(推荐):
java复制LambdaQueryWrapper<User> lambdaWrapper = Wrappers.lambdaQuery(); lambdaWrapper.eq(User::getDepartmentId, 5) .between(User::getCreateTime, start, end);
4. 扩展应用场景
4.1 审计字段自动填充
配合MetaObjectHandler实现自动填充:
java复制@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
@Override
public void insertFill(MetaObject metaObject) {
this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now());
}
@Override
public void updateFill(MetaObject metaObject) {
this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now());
}
}
4.2 多租户数据隔离
配置拦截器实现租户过滤:
java复制@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public Expression getTenantId() {
return new StringValue("当前租户ID");
}
}));
return interceptor;
}
5. 性能监控与调优
5.1 SQL执行分析
启用性能分析插件:
java复制@Bean
@Profile({"dev", "test"})
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor interceptor = new PerformanceInterceptor();
interceptor.setMaxTime(1000);
interceptor.setFormat(true);
return interceptor;
}
5.2 慢SQL监控
结合Druid数据源配置:
properties复制# 开启Druid监控
spring.datasource.druid.filter.stat.enabled=true
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=1000
实际项目中,BaseMapper的修改和查询功能远不止基础CRUD操作。通过合理使用Wrapper条件构造器、结合自定义SQL和MyBatis-Plus的扩展功能,可以构建出既保持简洁又功能强大的数据访问层。特别是在处理复杂业务逻辑时,Lambda表达式方式的链式调用能让代码既易于维护又类型安全。
