saveOrUpdate 有个缺点,不会把值赋值为null,解决办法

针对 MyBatis-Plus 的 saveOrUpdate 方法无法将字段更新为 null 的问题,这是因为 MyBatis-Plus 默认会忽略 null 值字段。以下是几种解决方案:

方案 1:使用 update(entity, wrapper) 手动指定更新条件

原理 :通过 UpdateWrapper 明确指定需要更新为 null 的字段。

java 复制代码
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    public void updateWithNullValue() {
        User user = new User();
        user.setId(1L);
        user.setUsername(null); // 需要更新为 null 的字段

        // 手动构建 UpdateWrapper,强制更新 null 值字段
        UpdateWrapper<User> wrapper = new UpdateWrapper<>();
        wrapper.set("username", null) // 指定 username 字段更新为 null
               .eq("id", user.getId()); // 更新条件:ID = 1

        // 调用 update 方法,第一个参数可以为 null(因为条件已在 wrapper 中)
        boolean success = this.update(null, wrapper);
        if (success) {
            System.out.println("更新 null 值成功");
        }
    }
}

方案 2:配置全局字段策略(推荐)

原理 :通过配置 FieldStrategy 让 MyBatis-Plus 不忽略 null 值。

方式 1:配置文件(application.yml)
yaml 复制代码
mybatis-plus:
  global-config:
    db-config:
      update-strategy: IGNORED  # 更新策略:忽略判断,所有字段都更新(包括 null)
方式 2:Java 配置类
java 复制代码
@Configuration
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 其他配置...
        
        // 配置全局策略
        GlobalConfig globalConfig = new GlobalConfig();
        GlobalConfig.DbConfig dbConfig = new GlobalConfig.DbConfig();
        dbConfig.setUpdateStrategy(FieldStrategy.IGNORED); // 更新时忽略字段非空判断
        globalConfig.setDbConfig(dbConfig);
        
        return interceptor;
    }
}

方案 3:使用 @TableField 注解(细粒度控制)

原理 :在实体类字段上指定更新策略为 IGNORED

java 复制代码
@Data
@TableName("t_user")
public class User {
    @TableId
    private Long id;
    
    @TableField(updateStrategy = FieldStrategy.IGNORED) // 该字段更新时忽略 null 判断
    private String username;
    
    private String phone;
    
    @TableField(updateStrategy = FieldStrategy.IGNORED) // 该字段更新时忽略 null 判断
    private Integer age;
}

方案 4:自定义 SQL 方法

原理 :在 Mapper 接口中自定义更新方法,使用 @Update 注解编写 SQL。

java 复制代码
public interface UserMapper extends BaseMapper<User> {

    @Update("UPDATE t_user SET username = #{username}, age = #{age} WHERE id = #{id}")
    boolean updateWithNull(@Param("id") Long id, 
                          @Param("username") String username, 
                          @Param("age") Integer age);
}

Service 层调用

java 复制代码
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    public void customUpdateWithNull() {
        boolean success = baseMapper.updateWithNull(1L, null, 25);
        if (success) {
            System.out.println("自定义 SQL 更新 null 值成功");
        }
    }
}

总结

方案 优点 缺点 适用场景
方案 1 灵活,按需更新 代码冗余 少量需要更新 null 的场景
方案 2 全局生效,无需修改代码 影响所有实体 项目中大量需要更新 null
方案 3 细粒度控制,不影响其他字段 需修改实体类 部分字段需要更新 null
方案 4 完全自定义 SQL 维护成本高 复杂更新逻辑或性能敏感场景

推荐顺序:方案 3(细粒度控制)→ 方案 2(全局配置)→ 方案 1(临时需求)→ 方案 4(特殊场景)。

相关推荐
luojiaao13 分钟前
【Python工具开发】k3q_arxml 简单但是非常好用的arxml编辑器,可以称为arxml杀手包
开发语言·python·编辑器
终焉代码14 分钟前
STL解析——list的使用
开发语言·c++
SoFlu软件机器人16 分钟前
智能生成完整 Java 后端架构,告别手动编写 ControllerServiceDao
java·开发语言·架构
英英_23 分钟前
视频爬虫的Python库
开发语言·python·音视频
猛犸MAMMOTH28 分钟前
Python打卡第46天
开发语言·python·机器学习
多多*1 小时前
微服务网关SpringCloudGateway+SaToken鉴权
linux·开发语言·redis·python·sql·log4j·bootstrap
梓仁沐白1 小时前
【Kotlin】协程
开发语言·python·kotlin
写bug写bug1 小时前
如何正确地对接口进行防御式编程
java·后端·代码规范
Cyanto1 小时前
Java并发编程面试题
java·开发语言·面试