java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > MyBatis Plus更新字段为null

MyBatis-Plus解决字段不更新为null的六大解决方案

作者:阿萨德528号

MyBatis-Plus 默认情况下不会将字段更新为 null,这是出于防止误操作的考虑,本文为大家整理了6个解决方法,大家可以根据自己的需求进行选择

MyBatis-Plus 默认情况下不会将字段更新为 null,这是出于防止误操作的考虑。以下是几种解决方案:

1.使用 UpdateWrapper(推荐)

UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("name", null)
            .set("age", null)
            .eq("id", 1);

userMapper.update(null, updateWrapper); // null表示不使用实体类传递参数

2.使用 LambdaUpdateWrapper(类型安全)

LambdaUpdateWrapper<User> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.set(User::getName, null)
            .set(User::getAge, null)
            .eq(User::getId, 1);

userMapper.update(null, updateWrapper); // null表示不使用实体类传递参数

3.实体类 + 字段策略配置(全局/局部)

全局配置(在配置文件中)

mybatis-plus:
  global-config:
    db-config:
      # 忽略null值字段,这里设置为false才会更新null值
      update-strategy: ignored
      # 可选值: 
      # ignored: 忽略null值(默认)
      # not_null: 只更新非null值
      # not_empty: 只更新非空值

局部配置(在字段上使用注解)

public class User {
    @TableField(strategy = FieldStrategy.IGNORED)  // 总是更新,包括null
    private String name;
    
    @TableField(updateStrategy = FieldStrategy.IGNORED)  // 仅更新时忽略策略
    private Integer age;
}

FieldStrategy 选项:

4.使用insertOrUpdate方法

User user = new User();
user.setId(1L);
user.setName(null);  // 需要结合字段策略配置

userMapper.insertOrUpdate(user);

5.自定义 SQL(复杂情况)

// 在 Mapper 接口中
@Update("UPDATE user SET name = null WHERE id = #{id}")
int updateNameToNull(@Param("id") Long id);

6.使用alwaysUpdateSomeColumnById方法(插件方式)

添加插件配置:

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new AlwaysUpdateSomeColumnByIdInnerInterceptor());
    return interceptor;
}

最佳实践建议

场景1:偶尔需要更新为null

// 使用 UpdateWrapper,不需要修改实体类注解
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.set("email", null)
      .eq("id", userId);
userMapper.update(null, wrapper);

场景2:特定字段经常需要更新为null

// 在实体类字段上添加注解
public class User {
    @TableField(updateStrategy = FieldStrategy.IGNORED)
    private String nickname;  // 该字段可以更新为null
}

场景3:批量更新为null

List<Long> ids = Arrays.asList(1L, 2L, 3L);
LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.set(User::getAvatar, null)
      .in(User::getId, ids);
userMapper.update(null, wrapper);

注意事项

常见问题

Q:为什么设置了null但数据库没更新?

A:检查字段是否使用了 @TableField(updateStrategy = NOT_NULL)(默认策略)

Q:如何让某个字段插入时可以为null,更新时不为null?

@TableField(insertStrategy = FieldStrategy.IGNORED, 
            updateStrategy = FieldStrategy.NOT_NULL)
private String phone;

Q:更新部分字段为null,部分字段保持原值?

User user = new User();
user.setId(1L);
user.setName(null);

LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<>();
wrapper.set(User::getName, null)      // 更新为null
      .set(User::getAge, user.getAge()) // 保持原值
      .eq(User::getId, user.getId());
userMapper.update(null, wrapper);

建议

根据具体场景选择合适的方法,一般推荐使用 UpdateWrapper 方式,因为它最灵活且不会影响其他操作的默认行为。

// ❌ 错误:实体对象无法设置null值(默认策略会忽略null)
User user = new User();
user.setId(1L);
user.setName(null);  // 这个null会被忽略,不会更新到数据库

UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.eq("id", 1);

userMapper.update(user, wrapper);  // name不会被更新为null

// ✅ 正确:使用wrapper.set()可以更新为null
UpdateWrapper<User> wrapper = new UpdateWrapper<>();
wrapper.set("name", null)  // 明确设置null值
      .eq("id", 1);

userMapper.update(null, wrapper);  // name会被更新为NULL

到此这篇关于MyBatis-Plus解决字段不更新为null的六大解决方案的文章就介绍到这了,更多相关MyBatis Plus更新字段为null内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文