在使用 MyBatis-Plus 进行数据库操作时,updateById 是我们最常用的更新方法之一。看似简单,但在实际开发中如果不注意细节,很容易踩坑——尤其是当字段为 null 时是否更新的问题。
🧩 问题背景:一个看似正常的更新逻辑
先来看一段常见的业务代码:
@Transactional(rollbackFor = Exception.class)
@Override
public void edit(BizUserEditParam bizUserEditParam) {
BizUser bizUser = this.queryEntity(bizUserEditParam.getId());
checkParam(bizUserEditParam);
boolean updateSuperAdminAccount = bizUser.getAccount().equals(BizBuildInEnum.BUILD_IN_USER_ACCOUNT.getValue()) &&
!bizUserEditParam.getAccount().equals(BizBuildInEnum.BUILD_IN_USER_ACCOUNT.getValue());
BeanUtil.copyProperties(bizUserEditParam, bizUser);
// 执行更新
this.updateById(bizUser);
}
这段代码的逻辑是:
看起来没问题?但关键在于:为什么非要先查一次?不能直接 new 一个对象 set id 和字段然后更新吗?
答案是:为了防止 null 值误更新,确保非空字段不被意外覆盖。
⚠️ 直接更新可能丢失数据!
假设我们不先查询,而是这样做:
BizUser user = new BizUser();
user.setId(bizUserEditParam.getId());
user.setAccount(bizUserEditParam.getAccount());
user.setName(bizUserEditParam.getName());
// 注意:前端没传 orgId,所以 orgId = null
this.updateById(user);
此时会发生什么?
📌 关键点:MyBatis-Plus 的字段更新策略
MyBatis-Plus 默认的字段策略是 FieldStrategy.NOT_NULL,即:只有非 null 的字段才会参与更新。
但如果你或团队配置了:
mybatis-plus:
global-config:
db-config:
update-strategy: ignored
忽略空值判断,实体对象的字段是什么值就用什么值更新,支持 null 值更新操作
那就意味着:即使字段是 null,也参与更新! 这会导致:
orgId = null 被写入数据库,原组织信息被清空!💥
✅ 正确做法:先查再更,保护已有数据
回到开头的代码:
BizUser bizUser = this.queryEntity(bizUserEditParam.getId());
BeanUtil.copyProperties(bizUserEditParam, bizUser);
this.updateById(bizUser);
“先查再更”不是性能浪费,而是数据安全的保障。
评论前必须登录!
注册