saveOrUpdate 有个缺点,不会把值赋值为null,解决办法
针对 MyBatis-Plus 的 saveOrUpdate
方法无法将字段更新为 null
的问题,这是因为 MyBatis-Plus 默认会忽略 null
值字段。以下是几种解决方案:
方案 1:使用 update(entity, wrapper)
手动指定更新条件
原理:通过 UpdateWrapper
明确指定需要更新为 null
的字段。
@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)
mybatis-plus:global-config:db-config:update-strategy: IGNORED # 更新策略:忽略判断,所有字段都更新(包括 null)
方式 2:Java 配置类
@Configuration
public class MyBatisPlusConfig {@Beanpublic 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
。
@Data
@TableName("t_user")
public class User {@TableIdprivate 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。
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 层调用:
@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(特殊场景)。