MyBatis-Plus 设置字段为 null 的几种方法总结

清欢
清欢
发布时间:2026-10-15 | 5人浏览过
原创

在使用 MyBatis-Plus 进行数据更新时,框架默认会忽略值为 null 的字段,这可能导致无法将特定字段重置为空。本文将解析这一行为背后的逻辑,并详细介绍如何通过自定义 SQL、@TableField 注解、UpdateWrapper API 以及全局配置来实现字段置 null 的操作,同时评估各方案的风险。

背景:为何默认无法设置字段为 null?

在使用 MyBatis-Plus 的通用方法(如 updateById)时,如果未手动编写 SQL,框架生成的更新语句默认会忽略实体类中值为 null 的字段。这意味着你无法直接将某个字段的值更新为数据库中的 null,除非该字段在数据库中本身默认就是 null。

这一设计主要是为了防止意外数据丢失。例如在执行“逻辑删除”时,通常只希望更新删除标记字段,而不希望其他业务字段被意外清空。如果 MP 将所有 null 字段都纳入更新范围,会导致非目标字段数据丢失;而若每次都全量查询并更新所有字段,则性能开销过大且操作繁琐。

处理方法

第1步:编写自定义 SQL(推荐,最安全)

目的: 完全掌控 SQL 生成过程,确保指定字段被明确设置为 null,无任何副作用。

操作:

  1. 在 Mapper XML 文件中定义 SQL 语句。
  2. 在 INSERT 或 UPDATE 语句中,显式设置对应字段为 NULL。
  3. 在 WHERE 条件中通过 ID 定位记录。

注意: 虽然这种方法最为稳妥,但对于字段较多仅需修改少量字段的场景,代码略显冗余。此时可考虑后续的方案,但需评估风险。

第2步:实体类添加 @TableField 注解(需慎用)

目的: 针对特定字段调整 MyBatis-Plus 的策略,使其在生成 SQL 时不过滤 null 值。

操作: 在实体类对应字段上添加 @TableField 注解,并设置相应的 Strategy。

@TableField(insertStrategy = FieldStrategy.IGNORED)   // Insert时忽略判断
@TableField(updateStrategy = FieldStrategy.IGNORED)   // Update时忽略判断
@TableField(whereStrategy = FieldStrategy.IGNORED)    // Where条件时忽略判断
// 或者组合使用
@TableField(insertStrategy = FieldStrategy.IGNORED, updateStrategy = FieldStrategy.IGNORED, whereStrategy = FieldStrategy.IGNORED)
private String yourField;

原理说明: FieldStrategy.IGNORED 表示无论字段值是什么(包括 null),都会将其纳入 SQL 语句中。

可选策略值:

  • NOT_NULL:字段不为 null 则更新(默认策略)。空字符串 "" 也会被更新。
  • NOT_EMPTY:字段不为空则更新。null 和 "" 都不会被更新。
  • DEFAULT:跟随全局配置。
  • IGNORED:忽略判断,始终更新。
  • NEVER:永远不更新该字段。

风险提示: 此方案仅对当前字段生效。如果在某些业务场景中,开发者忘记设置该字段的值(保持 null),由于注解的作用,该字段会被更新为 null,导致原有数据丢失。因此,除非充分理解其影响,否则不建议广泛使用。

第3步:使用 UpdateWrapper 的 set() 方法(推荐,适合批量或动态条件)

目的: 在编程式构建更新条件时,直接指定字段值为 null。

操作: 利用 MyBatis-Plus 3.x 提供的 UpdateWrapper API。

UpdateWrapper<TestIdcardEntity> updateWrapper = new UpdateWrapper<>;
updateWrapper.set("name", null);  // 显式设置字段名为 name 的值为 null
updateWrapper.eq("id", id);       // 设置更新条件
testIdcardService.update(updateWrapper);

优点: 灵活性强,无需修改实体类结构,且不会像全局配置那样产生副作用,是代码层面的最佳实践之一。

第4步:全局参数配置(高危,极少推荐)

目的: 修改框架默认行为,使所有实体的所有字段在处理 null 时都忽略判断。

操作: 在 YAML 配置文件中进行如下设置:

mybatis-plus:
  global-config:
    db-config:
      insert-strategy: ignored
      update-strategy: ignored
      select-strategy: ignored

警告:

  1. 这是全局生效的配置,会影响项目中所有实体类的所有字段。
  2. 一旦配置为 ignored,任何传入的 null 值都会被写入数据库,极易造成大规模数据丢失。
  3. 如果同时存在第二种方案的实体类注解,实体类注解优先级更高。

常见排错:更新后 null 未生效?

问题描述

调用 mapper.updateById(entity) 时,期望将某个字段设为 null,但数据库中该字段并未改变,而其他非 null 字段正常更新。

排查步骤

  1. 检查数据库约束: 确认该字段是否允许为 NULL。如果数据库字段定义为 NOT NULL,即使 MP 生成了 SET NULL 的 SQL,执行也会失败或被忽略。
  2. 检查字段策略: 确认是否为该字段配置了 @TableField(updateStrategy = FieldStrategy.IGNORED),或者使用了上述的 UpdateWrapper.set() 方法。
  3. 检查全局配置: 如果未使用注解,确认全局 field-strategy 是否被错误地改为了 0 (IGNORED),但这通常导致的是“反而能更新”,所以如果是“不能更新”,通常是因为默认为 NOT_NULL 且未加特殊处理。

总结

在 MyBatis-Plus 中将字段更新为 null,核心在于打破框架默认的“忽略 null”策略。推荐使用方法一(自定义 SQL)和方法三(UpdateWrapper.set),它们可控性强且风险低。
不推荐使用方法二(实体类注解)和方法四(全局配置),因为它们容易因开发疏忽导致非预期的数据覆盖,特别是在处理重要业务数据时需格外谨慎。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表