Mybatis-plus 更新 Null 的策略踩坑记

一个bug

在一个管理页面,有一个非必填字段被设置成空了并提交更新,再次打开的时候,发现字段还在,并没有被更新成功。

使用的数据库映射框架是 Mybatis-plus ,对于Mybatis 在更新字段的时候会对空进行校验,如果字段为 null,会被忽略加入 sql。

应对策略

推荐策略:使用 UpdateWrapper (3.x)

使用 UpdateWrapper 或 LambdaUpdateWrapper

这是官方给出的案例

less 复制代码
//updateAllColumnById(entity) // 全部字段更新: 3.0已经移除
mapper.update(
   new User().setName("mp").setAge(3),
   Wrappers.<User>lambdaUpdate()
           .set(User::getEmail, null) //把email设置成null
           .eq(User::getId, 2)
);
//也可以参考下面这种写法
mapper.update(
    null,
    Wrappers.<User>lambdaUpdate()
       .set(User::getAge, 3)
       .set(User::getName, "mp")
       .set(User::getEmail, null) //把email设置成null
       .eq(User::getId, 2)
);

通过这种方式,可以达到将字段设置成 null 的效果。

其他策略(不推荐并且慎用)

在字段上增加了 @TableField(updateStrategy = FieldStrategy.IGNORED)

在 DO 字段上添加这个更新策略,就是不会判断 null,任何时候都加入 sql

特别注意:这个策略,在高级版本中已经被 deprecated (3.5.3.2)

更新丢失风险 FieldStrategy.ALWAYS

意味着在每次更新操作中,都会将实体对象中的所有字段值写入数据库,无论这些字段的值是否为 null

风险巨大。

有一张用户表, 在 salary 上添加 FieldStrategy.ALWAYS

(id,name,age,salary)

开发A:通过 id 更新 age, 但是 DO 没有设置 salary了,mybaits-plus 会添加 salary ,最终导致 salary 被更新为 null,导致数据丢失。

这种问题如果不注意,后果十分严重,不建议在 DO 上添加此策略。随着业务发展,人员变动,这种操作会给以后埋下隐患。

另外使用这种策略以后,对于批量更新简直噩梦!慎重!

自定义 sql 方式

如果需要更复杂的逻辑来决定何时将字段设置为 null,可以选择编写自定义的 XML 映射文件或者使用 @Select, @Update 等注解来定义 SQL 语句,在其中明确写出 SET column_name = NULL

其他策略("曲线救国")

如果是 String 类型,可以设置成"",例如: MapStruct 设置一个默认值。

less 复制代码
@Mappings({
        @Mapping(source = "name", target = "name", defaultValue = "")
})
UpdateParam convert(Request request);

结束

  1. 谨慎使用策略 FieldStrategy.ALWAYS/ FieldStrategy.IGNORED
  2. 更新使用 UpdateWrapper 或 LambdaUpdateWrapper
相关推荐
Java水解2 分钟前
【Spring Boot】Spring 魔法世界:Bean 作用域与生命周期的奇妙之旅
spring boot·后端
西岭千秋雪_3 分钟前
Zookeeper监听机制
java·linux·服务器·spring·zookeeper
毕设源码-林学长7 分钟前
计算机毕业设计java和Vue的安全教育科普平台设计与实现 安全知识普及与教育平台 安全教育信息化管理平台
java·开发语言·课程设计
ruleslol11 分钟前
java-接口适配器模式 & jsk8 接口默认实现
java·适配器模式
JohnYan12 分钟前
Bun技术评估 - 26 Abort
javascript·后端·bun
逛逛GitHub15 分钟前
国产首个开源 AI 原生后端平台,这次是真起飞了。
后端·github
Python私教16 分钟前
Rust 编程语言基础知识全面介绍
开发语言·后端·rust
鬼火儿16 分钟前
网卡驱动架构以及源码分析
java·后端
老华带你飞25 分钟前
房屋租赁|房屋出租|房屋租赁系统|基于Springboot的房屋租赁系统设计与实现(源码+数据库+文档)
java·数据库·spring boot·vue·论文·毕设·房屋租赁系统
TDengine (老段)28 分钟前
TDengine 数学函数 ASCII 用户手册
java·大数据·数据库·物联网·时序数据库·tdengine·涛思数据