MyBatis-Plus updateById不更新null值


前言

在 MyBatis-Plus 中,使用updateById,null字段并不会更新,其实是和更新的策略有关,当然,也有插入策略,本文基于MyBatis-Plus3.5.2,对插入和更新策略做讲解。

方式一 调整全局的验证策略

注入全局配置,设置属性 insertStrategyupdateStrategy

缺点:这样做会对所有的字段都忽略判断,如果一些字段不想要修改,但是传值的时候没有传递过来,就会被更新为null

mybatis-plus:
  global-config:
    db-config:
      insert-strategy: ignored  # "忽略判断", 所有字段都插入
      update-strategy: ignored  # "忽略判断", 所有字段都更新

insertStrategyupdateStrategy 属性的值有以下5种枚举类型:

  • ignored “忽略判断”, 所有字段都更新或插入
  • not_null “非 NULL 判断”, 只更新或插入非NULL值
  • not_empty “非空判断”, 只更新或插入非NULL值且非空字符串
  • default 如果字段的值不为null,则进行插入或者更新操作;如果字段的值为null,不执行操作,执行结果还是数据库原来的值或者默认值
  • never 永远不进行插入或更新操作,即使字段的值不为null

方式二 调整字段验证注解

在属性上注解

根据具体情况,在需要更新或者插入的字段中调整验证注解,如忽略判断,任何情况都进行插入和更新操作:

@TableField(updateStrategy = FieldStrategy.IGNORED, insertStrategy = FieldStrategy.IGNORED)

方式三 使用 UpdateWrapper

如果没有设置 insert-strategyupdate-strategy 的值,默认为 default

使用以下方法来进行更新操作,无设置的值还是数据库原来的值,如下

UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("name", "一碗情深")
    .set("url", "https://blog.youkuaiyun.com/xiaohuihui1400")
    .eq("id", 1);
userMapper.update(null, updateWrapper);

或者使用lambda表达式,只有将属性赋值,数据库的值才会改变,如下,把email设置成null

mapper.update(
    null,
    Wrappers.<User>lambdaUpdate()
        .set(User::getName, "一碗情深")
		.set(User::getUrl, "https://blog.youkuaiyun.com/xiaohuihui1400")
        .set(User::getEmail, null) // 把email设置成null
        .eq(User::getId, 1)
);
<think>嗯,用户现在问的是在MyBatis-Plus中某个字段更新有什么办法。之前他们问过saveOrUpdate方法在字段为空时是否会更新,现在这个问题应该和之前有关联。可能用户在实际使用中遇到了某个字段被意外更新的情况,想找到避免的方法。 首先,我需要回忆一下MyBatis-Plus中控制字段更新的策略。记得之前回答过关于updateStrategy的内容,比如FieldStrategy.NOT_NULL是默认的,非空才更新。所以如果用户想让某个字段更新,无论是否为空,可能需要设置字段的更新策略为忽略,或者使用其他方法排除该字段。 可能的解决方案有几个: 1. 使用@TableField注解,设置updateStrategy为FieldStrategy.NEVER,这样该字段在更新时会被忽略。 2. 通过全局配置设置默认的更新策略,但这样会影响所有字段,可能推荐。 3. 使用UpdateWrapper来明确指定要更新的字段,排除更新的字段。 4. 使用selective方法,比如updateByIdSelective,只更新非空字段。 5. 在实体类中设置该字段的,让MyBatis-Plus在生成SQL时自动忽略。 然后需要具体解释每种方法的应用场景和示例。比如注解方式适合单个字段控制,而UpdateWrapper适合动态条件的情况。还要注意提到NEVER和NOT_NULL的区别,NOT_NULL是当字段非空时才会更新,而NEVER是无论字段如何都更新。 另外,用户可能对如何选择这些方法有疑问,需要给出最佳实践建议,比如推荐使用注解或UpdateWrapper,避免使用全局配置以防止意外影响其他字段。同时要提醒在需要动态排除字段时,使用Wrapper更灵活。 最后,确保回答结构清晰,分点说明,每种方法都有代码示例和注意事项,帮助用户理解并选择合适的方法。还要检查是否符合之前的系统级指令,比如数学公式和独立公式的正确使用,虽然这个问题可能太涉及数学内容,但如果有代码块需要正确标注。</think>在 MyBatis-Plus 中,若需要控制特定字段参与更新操作,可通过以下方案实现: --- ### 一、字段级控制方案 #### 1. 注解 `@TableField` 标记忽略更新 通过设置 `updateStrategy` 属性,直接禁止字段参与 **所有** `UPDATE` 操作: ```java public class User { @TableField(updateStrategy = FieldStrategy.NEVER) // 永久参与更新 private String createTime; // 例如创建时间字段 } ``` - **行为**:无论字段是否为空,均会出现在 `UPDATE` 语句中 - **适用场景**:需要永久性保护字段(如审计字段、逻辑删除标记) --- #### 2. 动态空过滤(默认行为) 若未显式配置策略,默认采用 `FieldStrategy.NOT_NULL`: ```java public class User { private Integer age; // 默认策略:仅当 age 非空时参与更新 } ``` - **行为**:字段为 `null` 时自动忽略更新 - **适用场景**:临时性跳过未赋的字段 --- ### 二、操作级控制方案 #### 1. 使用 `UpdateWrapper` 明确更新字段 通过 Lambda 表达式精准控制更新的字段范围: ```java UpdateWrapper<User> wrapper = new UpdateWrapper<>(); wrapper .set("name", user.getName()) // 指定要更新的字段 .set("email", user.getEmail()) .eq("id", user.getId()); // 限定条件 userService.update(wrapper); ``` - **优点**:动态控制更新字段,避免字段污染 - **典型场景**:前端仅传递部分需修改的字段时 --- #### 2. 选择性更新方法 `updateByIdSelective` ```java User user = new User(); user.setId(1L); user.setName("NewName"); // 只设置需要更新的字段 userService.updateById(user); // 自动忽略未赋字段 ``` - **原理**:基于 `NOT_NULL` 策略,未赋的字段(保持 `null`)参与更新 --- ### 三、全局配置方案(谨慎使用) 修改全局字段更新策略(优先级低于注解配置): ```yaml mybatis-plus: global-config: db-config: update-strategy: not_null # 全局默认更新策略 ``` - **风险提示**:可能影响其他未显式配置注解的字段行为 --- ### 四、特殊场景处理 #### 强制保留字段原 若需在更新时保留数据库中的原(即使实体类字段为 `null`): ```java User dbUser = userService.getById(1L); // 先查询当前 dbUser.setName("NewName"); // 仅修改目标字段 userService.updateById(dbUser); // 其他字段保持原 ``` --- ### 最佳实践总结 | 方案 | 控制粒度 | 灵活性 | 推荐场景 | |--------------------|----------|--------|------------------------| | `@TableField` 注解 | 字段级 | 低 | 需永久保护的关键字段 | | `UpdateWrapper` | 操作级 | 高 | 动态业务逻辑 | | 选择性更新方法 | 操作级 | 中 | 简单局部更新 | | 全局配置 | 全局 | 低 | 统一规范(需谨慎评估) | 通过组合使用上述策略,可精准控制 MyBatis-Plus 的字段更新行为,避免数据意外覆盖。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一碗情深

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值