MyBatis-Plus?updateById更新不了空字符串或null的解決方法
1. 文章引言
在開發(fā)的過程中,我們經(jīng)常使用MyBatis-Plus的updateById方法更新數(shù)據(jù)表,但今天在更新appConfig表時,發(fā)現(xiàn)無法將content字段更新為null。
如下是我的測試代碼:
@Test
public void testUpdateById() {
Long id = 10L;
AppConfig beforeAppConfig = appConfigService.getById(id);
System.out.println("輸出更新 前 的應用配置內(nèi)容:" + beforeAppConfig.getContent());
System.out.println();
// 將 id = 10的應用配置的內(nèi)容修改 null
beforeAppConfig.setContent(null);
appConfigService.updateById(beforeAppConfig);
// 查詢更新的 id = 10的應用配置的內(nèi)容
AppConfig afterAppConfig = appConfigService.getById(id);
System.out.println("輸出更新 后 的應用配置內(nèi)容:"+afterAppConfig.getContent());
}
輸出結(jié)果如下圖所示:

由上圖可知,更新前后輸出的內(nèi)容不變。
換句話說,上述此代碼 beforeAppConfig.setContent(null);雖然設置content為null,但數(shù)據(jù)庫并沒有將content更新為null。
這是什么原因呢?
2. 分析問題
想要搞清楚沒有將content更新為null原因,我們不妨看看上圖中的用綠色框圈出來的MyBatis-Plus打印出的mysql語句,如下所示:
UPDATE app_config SET create_time=? WHERE id=?
你會清楚地看到,mysql語句中沒有content字段。
按照預期結(jié)果,MyBatis-Plus打印出的mysql語句應該如下:
UPDATE app_config SET create_time=?, content=? WHERE id=?
為什么MyBatis-Plus沒有按預期打印出的mysql語句,經(jīng)過查找資料可得。
其實是MyBatis-Plus對字段的驗證策略導致的,MyBatis-Plus默認進行了不是全量更新的策略。
查閱官網(wǎng)發(fā)現(xiàn)有一個屬性,而我的application.yml沒有配置這個屬性,如下代碼所示:
#mybatis配置
mybatis-plus:
mapper-locations: classpath*:/mapper/*Mapper.xml
type-aliases-package: com.superjson.superjsonmanager.mapper
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 按下劃線轉(zhuǎn)駝峰規(guī)則映射數(shù)據(jù)庫字段與java bean屬性之間的關系
map-underscore-to-camel-case: true
# 關閉一級緩存
# local-cache-scope: statement
# 關閉二級緩存
# cache-enabled: false
global-config:
db-config:
id-type: auto
logic-delete-value: -1
logic-not-delete-value: 0
如果沒有配置這個屬性,那么,MyBatis-Plus采用了默認的字段驗證策略。
這個屬性就是field-strategy,在原application.yml中加入該屬性,如下代碼所示:
global-config:
#字段策略 0:忽略判斷,1:非NULL判斷,2:非空判斷
field-strategy: 1
db-config:
id-type: auto
logic-delete-value: -1
logic-not-delete-value: 0
field-strategy字段更新插入策略屬性說明:
IGNORED(0): “忽略判斷”, 所有字段都更新和插入NOT_NULL(1):“非 NULL 判斷”, 只更新和插入非NULL值NOT_EMPTY(2):“非空判斷”,只更新和插入非NULL值且非空字符串
field-strategy默認策略是NOT_NULL(1) ,即更新的時候做了null判斷,默認不更新為null的傳參。
3. 解決問題
既然知道了問題所在,便可以通過如下三種方式解決。
3.1 方法1:全局配置方式
在MyBatis-Plus配置文件中修改field-strategy字段驗證的值為0,即忽略判斷,如下代碼所示:
global-config:
#字段策略 0:"忽略判斷",1:"非 NULL 判斷"),2:"非空判斷"
field-strategy: 0
db-config:
id-type: auto
logic-delete-value: -1
logic-not-delete-value: 0
如是配置后,并參照網(wǎng)上說的,在PO對象(即@TableField(value="content")修飾字段的時候,還需要加入el屬性,但我是新版本的MyBatis-Plus,已經(jīng)不支持el屬性了,如下源碼所說:

我雖然在content對象上加上update屬性,如下代碼所示:
/** 配置內(nèi)容 */ @TableField(value = "content",update = "null" ) private String content;
仍無法將content字段修改為null,如下圖所示:

如果有知道的,可以在評論區(qū)中留言,不勝感激。
此外,如果你的MyBatis-Plus版本支持el。你在設置了 field-strategy: 0的前提下,同時你已確保了你的PO對象(即@TableField(value="XSID")修飾字段加入了el屬性 (每個屬性對應數(shù)據(jù)庫的jdbcType類型,這樣才能成功更新空值或null),如下圖:

你可以采用el的這種方式修改。
3.2 方法2:非null字段驗證策略

配置完成后,測試類修改完成,并重新啟動,如下圖所示:

此時,你會發(fā)現(xiàn)可以更新空字符串' ',如下圖所示:

但是一些比如Date等對象類型的設置空是要設置為null的,你會發(fā)現(xiàn)一樣更新不了null。
3.3 方法3:通過注解的方式
由于表中的字段基本上都是varchar字符類型的,所以此時可以在PO中對類型為對象類型的屬性,通過注解對對象類型的屬性單獨設置字段驗證策略為IGNORED,如下代碼所示:
/** 配置內(nèi)容 */ @TableField(value = "content",updateStrategy = FieldStrategy.IGNORED) private String content;
同時修改測試代碼,如下圖所示:

這樣就可以成功更新值為null或者空字符串' '了,問題解決,如下圖所示:

如果你的MyBatis-Plus版本和我的版本不同,你可能是下圖中的注解,同樣能解決問題。

4. 總結(jié)
到此這篇關于MyBatis-Plus updateById更新不了空字符串或null的解決方法的文章就介紹到這了,更多相關MyBatis-Plus updateById更新 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
eclipse的web項目實現(xiàn)Javaweb購物車的方法
這篇文章主要介紹了eclipse的web項目實現(xiàn)Javaweb購物車的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-10-10
SpringBoot實現(xiàn)動態(tài)多線程并發(fā)定時任務
這篇文章主要為大家詳細介紹了SpringBoot實現(xiàn)動態(tài)多線程并發(fā)定時任務,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-05-05
Jenkins自動構(gòu)建部署項目到遠程服務器上的方法步驟
這篇文章主要介紹了Jenkins自動構(gòu)建部署項目到遠程服務器上的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-01-01
Java創(chuàng)建多線程局域網(wǎng)聊天室實例
這篇文章主要介紹了Java創(chuàng)建多線程局域網(wǎng)聊天室實例,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下2021-07-07
詳解java中this.getClass()和super.getClass()的實例
這篇文章主要介紹了詳解java中this.getClass()和super.getClass()的實例的相關資料,需要的朋友可以參考下2017-08-08

