在 mybatis-plus 里,更新 null 字段是一个非常常见、也非常容易踩坑的问题。
很多人会遇到这种情况:
我明明 setxxx(null) 了,为什么数据库里还是原来的值?
下面我按 原因 → 解决方案 → 使用建议 来整理一下。
一、为什么 mybatis-plus 默认不更新 null?
这是 mybatis-plus 的设计行为,不是 bug。
默认情况下:
@tablefield(updatestrategy = fieldstrategy.not_null)
也就是说:
字段为
null,就不会出现在 update 语句里
目的是为了:
- • 防止误操作把字段更新成
null - • 更符合大多数“只更新有值字段”的业务场景
所以你写:
user user = new user(); user.setid(1l); user.setemail(null); usermapper.updatebyid(user);
实际生成的 sql 类似:
update user set id = ? where id = ?
email 根本没参与更新。
二、更新 null 的几种正确方式(重点)
方式一:使用@tablefield(updatestrategy = fieldstrategy.ignored)(最推荐)
@tablefield(updatestrategy = fieldstrategy.ignored) private string email;
含义是:
不管是不是 null,都参与 update
这时:
user.setemail(null); usermapper.updatebyid(user);
生成 sql:
update user set email = null where id = ?
适合场景
- • 这个字段本来就允许被清空
- • 例如:备注、头像、手机号、邮箱
方式二:在实体类级别统一策略
@tablename(value = "user", autoresultmap = true)
public class user {
}
配合全局配置(不太常用,可以了解):
mybatis-plus: global-config: db-config: update-strategy: ignored
慎用
- • 会导致所有字段都能被更新为 null
- • 风险较大,不适合复杂业务
方式三:使用updatewrapper(最灵活)
如果你不想改实体类:
updatewrapper<user> wrapper = new updatewrapper<>();
wrapper.eq("id", 1l)
.set("email", null);
usermapper.update(null, wrapper);
生成 sql:
update user set email = null where id = ?
适合场景
- • 后台管理
- • 批量操作
- • 精准控制 sql
方式四:使用lambdaupdatewrapper
lambdaupdatewrapper<user> wrapper = wrappers.lambdaupdate(); wrapper.eq(user::getid, 1l) .set(user::getemail, null); usermapper.update(null, wrapper);
类型安全、ide 友好,实际项目更推荐
三、一个容易忽略的坑
逻辑删除字段 + 更新 null
如果你用了:
@tablelogic private integer deleted;
一定要确认:
wrapper里有没有被逻辑删除条件影响- 有些更新失败,其实是 被逻辑删除过滤了
到此这篇关于mybatis-plus 默认不更新null的4种方法的文章就介绍到这了,更多相关mybatis-plus 默认不更新null内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论