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

 更新时间:2026年01月05日 09:41:32   作者:阿萨德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 选项:

  • IGNORED:忽略判断,总是更新(包括null)
  • NOT_NULL:非 NULL 判断(默认)
  • NOT_EMPTY:非空判断(字符串额外检查空串)
  • NEVER:不加入SQL

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);

注意事项

  • 性能考虑FieldStrategy.IGNORED 会使该字段在所有更新操作中都参与SQL生成
  • 数据安全:谨慎使用全局配置,防止误操作
  • 推荐做法:需要更新为null的字段使用注解,其他字段保持默认
  • 版本兼容:不同版本的MyBatis-Plus可能有不同的策略名称

常见问题

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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • springboot注解及GET、POST接口写法

    springboot注解及GET、POST接口写法

    springboot提供了@Contrller和@RestController注解,@Controller返回页面和数据而@RestController返回数据,本文重点介绍springboot注解及GET、POST接口写法,感兴趣的朋友一起看看吧
    2024-04-04
  • Java List的remove()方法陷阱以及性能优化

    Java List的remove()方法陷阱以及性能优化

    Java List在进行remove()方法是通常容易踩坑,本文就详细的介绍一下陷阱以及性能优化,感兴趣的可以了解一下
    2021-10-10
  • 创建一个Java的不可变对象

    创建一个Java的不可变对象

    这篇文章主要介绍了创建一个Java的不可变对象,一个类的对象在通过构造方法创建后如果状态不会再被改变,那么它就是一个不可变(immutable)类。它的所有成员变量的赋值仅在构造方法中完成,不会提供任何 setter 方法供外部类去修改,需要的朋友可以参考下
    2021-11-11
  • MyBatis 探秘之#{} 与 ${} 参传差异解码(数据库连接池筑牢数据交互根基)

    MyBatis 探秘之#{} 与 ${} 参传差异解码(数据库连接池筑牢数据交互

    本文详细介绍了MyBatis中的`#{}`和`${}`的区别与使用场景,包括预编译SQL和即时SQL的区别、安全性问题,以及如何正确使用数据库连接池来提高性能,感兴趣的朋友一起看看吧
    2024-12-12
  • SpringBoot集成AOP的代码示例

    SpringBoot集成AOP的代码示例

    AOP是一种编程范式,它旨在将横切关注点(cross-cutting concerns)从应用程序的业务逻辑中分离出来,横切关注点是那些在多个模块中重复出现的功能,如日志记录、性能监控、事务管理、安全控制等,本文介绍了Spring Boot如何集成AOP,需要的朋友可以参考下
    2024-09-09
  • 客户端设置超时时间真的很重要

    客户端设置超时时间真的很重要

    今天小编就为大家分享一篇关于客户端设置超时时间真的很重要,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 详解Java的JDBC API中事务的提交和回滚

    详解Java的JDBC API中事务的提交和回滚

    这篇文章主要介绍了Java的JDBC API中事务的提交和回滚,JDBC是Java用于和数据库软件连接的API,需要的朋友可以参考下
    2015-12-12
  • Java反射机制的适用场景及利弊详解

    Java反射机制的适用场景及利弊详解

    这篇文章主要介绍了Java反射机制的适用场景及利弊详解,Spring用到很多反射机制,在xml文件或者properties里面写好了配置,然后在Java类里面解析xml或properties里面的内容,得到一个字符串,然后用反射机制,需要的朋友可以参考下
    2023-08-08
  • Java Volatile关键字同步机制详解

    Java Volatile关键字同步机制详解

    这篇文章主要介绍了Java Volatile关键字同步机制详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-04-04
  • J2ME编程中的几个重要概念介绍

    J2ME编程中的几个重要概念介绍

    本文介绍的是J2ME编程应用平台中的几个重要概念,希望对你有帮助,一起来看。
    2015-09-09

最新评论