开发者

MyBatis-Plus更新字段为null的三种解决方案

开发者 https://www.devze.com 2025-10-11 10:26 出处:网络 作者: 一勺菠萝丶
目录问题示例方案 1:修改实体类策略,让 null 也更新方案 2:使用 UpdateWrapper 或 LambdaUpdateWrapper 动态更新方案 3:自定义 Mapper SQL小结总结在使用 MyBATis-Plus 进行数据库更新时,很多小伙伴会遇到一个问
目录
  • 问题示例
  • 方案 1:修改实体类策略,让 null 也更新
  • 方案 2:使用 UpdateWrapper 或 LambdaUpdateWrapper 动态更新
  • 方案 3:自定义 Mapper SQL
  • 小结
  • 总结

在使用 MyBATis-Plus 进行数据库更新时,很多小伙伴会遇到一个问题:

当某android个字段传了 null 时,updateById 默认 不会更新该字段,数据库里的值依然保留。

这个问题在你想把字段置空时就会很麻烦。下面我给大家讲几个解决方案,小白也能快速上手。

问题示例

假设我们有一个更新方法:

@Override
@Transactional(rollbackFor = Exception.class)
public void updateCarousel(@Valid CarouselUpdateReqVO updateReqVO) {
    // 校验记录存在
    validateCarouselExists(updateReqVO.getId());

    // 转换实体类
    CarouselDO updateObj = BeanUtils.toBean(updateReqVO, CarouselDO.class);

    // 更新数据库
    carouselMapper.updateById(updateObj);
}

如果 updateReqVO.getLinkId()null,执行 updateById 后,link_id 不会被更新,数据库值不会变成 null

这是 MyBatis-Plus 默认策略导致的,它默认 忽略 null 值字段

http://www.devze.com案 1:修改实体类策略,让 null 也更新

MyBatis-Plus 提供了 @TableField(updateStrategy = FieldStrategy) 来控制字段更新策略。

import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.annotation.TableField;

@TableField(updateStrategy = FieldStrategy.ALWAYS)
private Long linkId;

策略说明:

策略作用
ALWAYS永远更新,即使字段为 null,也会更新到数据库
NOT_NULL默认值,字段为 null 时不会更新
NOT_EMPTY字符串类型使用,空字符串也会忽略
NEVER永不更新
DEFAULT使用全局默认策略

如果字段使用 ALWAYS,当你传 null 时,就会把数据库字段置空。

优点:简单直接,只javascript需改实体类。

缺点:全局生效,可能影响其它更新场景。

方案 2:使用 UpdateWrapper 或 LambdaUpdateWrapper 动态更新

如果你只想在某次更新操作中支持 null 更新,而不改实体类,可以手动构建更新条件:

CarouselDO updateObj = BeanUtils.toBean(updateReqVO, CarouselDO.class);

LambdaUpdateWrapper<CarouselDO> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(CaroupythonselDO::getId, updateObj.getId())
       .set(CarouselDO::getLinkId, updateObj.getLinkId()); // null 也可以更新

carouselMapper.update(null, wrapper);

或者使用普通 UpdateWrapper:

UpdateWrapper<CarouselDO> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", updateObj.getId())
             .set("link_id", updateObj.getLinkId()); // null 也可以更新

carouselMapper.update(updateObj, updateWrapper);

优点:灵活,只针对当前更新操作生效。

缺点:字段较多时,需要手动写每个字段。

方案 3:自定义 Mapper SQL

当字段较多或者更新规则复杂时,可以直接写自定义 SQL:

<update id="updateCarousel">
    update carousel
    set
        link_id = #{linkId},
        title = #{title},
        description = #{description}
    where id = #{id}
</update>

完全控制字段更新规则,包括 null 值编程客栈

失去 MyBatis-Plus 自动映射便利。

小结

方案优点缺点适用场景
实体类设置 ALWAYS简单,全局生效影响所有更新操作字段允许全局置空
LambdaUpdateWrapper / UpdateWrapper灵活,针对单次操作写法稍复杂单次更新可能置空字段
自定义 Mapper SQL完全控制,适合复杂场景失去自动映射批量或复杂更新

推荐做法

  • 偶尔置空 → 用 方案 2
  • 经常置空 → 用 方案 1
  • 更新逻辑复杂 → 用 方案 3

总结

MyBatis-Plus 默认忽略 null 值是为了安全,但当你需要置空数据库字段时,需要使用 FieldStrategy.ALWAYS 或手动更新。

掌握这几种方式后,你就能灵活处理 null 值字段更新,不再受默认策略限制。

到此这篇关于MyBatis-Plus更新字段为null的三种解决方案的文章就介绍到这了,更多相关MyBatis Plus更新字段为null内容请搜索编程客栈(www.devze.com)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号