MyBatis-Plus更新字段為null的三種解決方案
在使用 MyBatis-Plus 進(jìn)行數(shù)據(jù)庫更新時,很多小伙伴會遇到一個問題:
當(dāng)某個字段傳了 null 時,updateById 默認(rèn) 不會更新該字段,數(shù)據(jù)庫里的值依然保留。
這個問題在你想把字段置空時就會很麻煩。下面我給大家講幾個解決方案,小白也能快速上手。
問題示例
假設(shè)我們有一個更新方法:
@Override
@Transactional(rollbackFor = Exception.class)
public void updateCarousel(@Valid CarouselUpdateReqVO updateReqVO) {
// 校驗(yàn)記錄存在
validateCarouselExists(updateReqVO.getId());
// 轉(zhuǎn)換實(shí)體類
CarouselDO updateObj = BeanUtils.toBean(updateReqVO, CarouselDO.class);
// 更新數(shù)據(jù)庫
carouselMapper.updateById(updateObj);
}
如果 updateReqVO.getLinkId() 為 null,執(zhí)行 updateById 后,link_id 不會被更新,數(shù)據(jù)庫值不會變成 null。
這是 MyBatis-Plus 默認(rèn)策略導(dǎo)致的,它默認(rèn) 忽略 null 值字段。
方案 1:修改實(shí)體類策略,讓 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 | 永遠(yuǎn)更新,即使字段為 null,也會更新到數(shù)據(jù)庫 |
| NOT_NULL | 默認(rèn)值,字段為 null 時不會更新 |
| NOT_EMPTY | 字符串類型使用,空字符串也會忽略 |
| NEVER | 永不更新 |
| DEFAULT | 使用全局默認(rèn)策略 |
如果字段使用 ALWAYS,當(dāng)你傳 null 時,就會把數(shù)據(jù)庫字段置空。
優(yōu)點(diǎn):簡單直接,只需改實(shí)體類。
缺點(diǎn):全局生效,可能影響其它更新場景。
方案 2:使用 UpdateWrapper 或 LambdaUpdateWrapper 動態(tài)更新
如果你只想在某次更新操作中支持 null 更新,而不改實(shí)體類,可以手動構(gòu)建更新條件:
CarouselDO updateObj = BeanUtils.toBean(updateReqVO, CarouselDO.class);
LambdaUpdateWrapper<CarouselDO> wrapper = new LambdaUpdateWrapper<>();
wrapper.eq(CarouselDO::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);
優(yōu)點(diǎn):靈活,只針對當(dāng)前更新操作生效。
缺點(diǎn):字段較多時,需要手動寫每個字段。
方案 3:自定義 Mapper SQL
當(dāng)字段較多或者更新規(guī)則復(fù)雜時,可以直接寫自定義 SQL:
<update id="updateCarousel">
update carousel
set
link_id = #{linkId},
title = #{title},
description = #{description}
where id = #{id}
</update>
完全控制字段更新規(guī)則,包括 null 值。
失去 MyBatis-Plus 自動映射便利。
小結(jié)
| 方案 | 優(yōu)點(diǎn) | 缺點(diǎn) | 適用場景 |
|---|---|---|---|
| 實(shí)體類設(shè)置 ALWAYS | 簡單,全局生效 | 影響所有更新操作 | 字段允許全局置空 |
| LambdaUpdateWrapper / UpdateWrapper | 靈活,針對單次操作 | 寫法稍復(fù)雜 | 單次更新可能置空字段 |
| 自定義 Mapper SQL | 完全控制,適合復(fù)雜場景 | 失去自動映射 | 批量或復(fù)雜更新 |
推薦做法:
- 偶爾置空 → 用 方案 2
- 經(jīng)常置空 → 用 方案 1
- 更新邏輯復(fù)雜 → 用 方案 3
總結(jié)
MyBatis-Plus 默認(rèn)忽略 null 值是為了安全,但當(dāng)你需要置空數(shù)據(jù)庫字段時,需要使用 FieldStrategy.ALWAYS 或手動更新。
掌握這幾種方式后,你就能靈活處理 null 值字段更新,不再受默認(rèn)策略限制。
到此這篇關(guān)于MyBatis-Plus更新字段為null的三種解決方案的文章就介紹到這了,更多相關(guān)MyBatis Plus更新字段為null內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java實(shí)現(xiàn)文本文件刪除空行的示例分享
這篇文章主要介紹了java實(shí)現(xiàn)文本文件刪除空行的示例,需要的朋友可以參考下2014-04-04
Spring中BeanFactory和ApplicationContext的作用和區(qū)別(推薦)
這篇文章主要介紹了Spring中BeanFactory和ApplicationContext的作用和區(qū)別,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09
SpringBoot實(shí)現(xiàn)圖片防盜鏈技術(shù)的原理分析與解決
這篇文章主要為大家詳細(xì)介紹了SpringBoot中實(shí)現(xiàn)圖片防盜鏈技術(shù)的原理分析與完整解決方案,文中的示例代碼講解詳細(xì),需要的可以了解一下2025-07-07
快速校驗(yàn)實(shí)體類時,@Valid,@Validated,@NotNull注解無效的解決
這篇文章主要介紹了快速校驗(yàn)實(shí)體類時,@Valid,@Validated,@NotNull注解無效的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10
java 文件大數(shù)據(jù)Excel下載實(shí)例代碼
這篇文章主要介紹了java 文件大數(shù)據(jù)Excel下載實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-04-04
淺析Java迭代器Iterator和Iterable的區(qū)別
Java語言中,Iterator和Iterable都是用來遍歷集合類數(shù)據(jù)結(jié)構(gòu)的接口,雖然它們有很多相似的地方,但在具體實(shí)現(xiàn)中卻有著一些不同之處,本文將詳細(xì)分析它們的區(qū)別,并提供相應(yīng)的代碼示例,需要的朋友可以參考下2023-07-07
基于HttpServletResponse 相關(guān)常用方法的應(yīng)用
本篇文章小編為大家介紹,基于HttpServletResponse 相關(guān)常用方法的應(yīng)用,需要的朋友參考下2013-04-04

