Mybatis-Plus中updateById方法不能更新空值問題解決
問題描述
在Mybatis-Plus中調(diào)用updateById方法進(jìn)行數(shù)據(jù)更新默認(rèn)情況下是不能更新空值字段的。而在實際開發(fā)過程中,往往會遇到需要將字段值更新為空值的情況。
那么如果讓Mybatis-Plus中的updateById方法支持空值更新呢?
演示:
實體User:
@TableName(value ="user")
@Data
public class User implements Serializable {
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer age;
private String email;
}
updateById方法單元測試:
@Test
public void testUpdateById() {
System.out.println("----- updateById method test ------");
User user = new User();
user.setId(1543920054188400641L);
user.setName("test");
user.setAge(13);
//user.setEmail();
userMapper.updateById(user);
System.out.println(user.toString());
}
執(zhí)行結(jié)果:

可以看到由于email字段的值為null,所以執(zhí)行updateById方法時沒有對email字段進(jìn)行更新。
原因分析:
Mybatis-Plus中字段的更新策略是通過FieldStrategy屬性控制的。
在實體字段上,如果不通過@TableField注解指定字段的更新策略,字段默認(rèn)的更新策略是FieldStrategy.DEFAULT,即跟隨全局策略。
而Mybatis-Plus的全局配置中,字段的默認(rèn)更新策略是FieldStrategy.NOT_NULL,即進(jìn)行空值判斷,不對NULL值數(shù)據(jù)進(jìn)行處理。
public DbConfig() {
this.idType = IdType.ASSIGN_ID;
this.tableUnderline = true;
this.capitalMode = false;
this.logicDeleteValue = "1";
this.logicNotDeleteValue = "0";
this.insertStrategy = FieldStrategy.NOT_NULL;
this.updateStrategy = FieldStrategy.NOT_NULL;
this.whereStrategy = FieldStrategy.NOT_NULL;
}
相關(guān)文檔:
Mybatis-Plus字段策略FieldStrategy詳解
Tip??:
官網(wǎng)鏈接,自力更生。
解決方案:
1、設(shè)置字段級別的更新策略IGNORED
如果只需要實體中的幾個字段支持空值更新,則通過@TableField注解指定字段的更新策略為FieldStrategy.IGNORED,忽略空值判斷,直接更新即可。
該方式的控制級別是字段級別的控制。
實體User:
@TableName(value ="user")
@Data
public class User implements Serializable {
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer age;
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String email;
}
再次執(zhí)行上面的單元測試:

email字段雖然是空值,但仍然進(jìn)行了更新操作,說明此時email字段已經(jīng)支持空值更新。
2、設(shè)置全局更新策略IGNORED
如果需要全局所有實體的更新操作都需要支持空值更新,可以修改Mybatis-Plus的全局更新策略。
該方式的控制級別是項目級別的控制。
在spring boot中修改如下屬性即可:
mybatis-plus.global-config.db-config.update-strategy=ignored
測試:
實體User:
@TableName(value ="user")
@Data
public class User implements Serializable {
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer age;
private String email;
}
單元測試:
@Test
public void testUpdateById() {
System.out.println("----- updateById method test ------");
User user = new User();
user.setId(1543920054188400641L);
user.setName("test");
//user.setAge(13);
//user.setEmail();
userMapper.updateById(user);
System.out.println(user.toString());
}
執(zhí)行結(jié)果:

age和email字段都支持空值更新,說明全局更新策略ignored生效。
3、采用alwaysUpdateSomeColumnById方法進(jìn)行全字段更新
Mybatis-Plus中自帶的擴展方法alwaysUpdateSomeColumnById會忽略字段的更新策略,直接對實體中的每一個字段都執(zhí)行更新操作。
如果你不想修改全局的字段更新策略,又需要項目中某個實體的所有字段都支持空值更新,推薦采用該方法。
該方式的控制級別是實體級別的控制。
實現(xiàn)步驟:
1、繼承DefaultSqlInjector擴展sql注入器,注入AlwaysUpdateSomeColumnById方法
public class MySqlInjector extends DefaultSqlInjector {
@Override
public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
List<AbstractMethod> methodList = super.getMethodList(mapperClass,tableInfo);
//自動填充策略為更新填充策略時,不用插入值
methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
//自動填充策略為插入時自動填充時,字段不用更新
methodList.add(new AlwaysUpdateSomeColumnById(i -> i.getFieldFill() != FieldFill.INSERT));
return methodList;
}
}
2、將擴展的sql注入器配置到spring容器中
@Configuration
public class MybatisPlusConfig {
@Bean
public MySqlInjector sqlInjector() {
return new MySqlInjector();
}
}
3、擴展自己的通用Mapper接口CommonMapper
public interface CommonMapper<T> extends BaseMapper<T> {
/**
* 全量插入,等價于insert
* @param entityList
* @return
*/
int insertBatchSomeColumn(List<T> entityList);
/**
* 全字段更新,不會忽略null值
* @param entity
* @return
*/
int alwaysUpdateSomeColumnById(@Param("et") T entity);
}
4、UserMapper繼承自定義的CommonMapper
public interface UserMapper extends CommonMapper<User> {
}
5、實體User
@TableName(value ="user")
@Data
public class User implements Serializable {
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Long id;
private String name;
private Integer age;
private String email;
}
6、單元測試
@Test
public void testUpdateById() {
System.out.println("----- updateById method test ------");
User user = new User();
user.setId(1543920054188400641L);
user.setName("test");
user.setAge(13);
//user.setEmail();
userMapper.alwaysUpdateSomeColumnById(user);
System.out.println(user.toString());
}
執(zhí)行結(jié)果:

雖然沒有修改Mybatis-Plus全局的更新策略,也沒有在實體字段上使用@TableField注解修改字段的更新策略,但是alwaysUpdateSomeColumnById方法仍然可以對空值字段進(jìn)行更新。
小結(jié):
本文主要是對Mybatis-Plus中updateById方法不能更新空值問題進(jìn)行了分析說明,并提供了3種解決方案。
字段級別解決方案
采用@TableField注解修改字段默認(rèn)的更新策略為FieldStrategy.IGNORED。
@TableField(updateStrategy = FieldStrategy.IGNORED) private String email;
實體級別解決方案
調(diào)用Mybatis-Plus中的擴展方法alwaysUpdateSomeColumnById,忽略字段更新策略,直接對實體中所有字端進(jìn)行更新。
全局級別解決方案
修改Mybatis-Plus的全局更新策略為ignored
mybatis-plus.global-config.db-config.update-strategy=ignored
到此這篇關(guān)于Mybatis-Plus中updateById方法不能更新空值問題解決的文章就介紹到這了,更多相關(guān)Mybatis-Plus updateById空值內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
解決在Gradle/IDEA中無法正常使用readLine的問題原因
這篇文章主要介紹了在Gradle/IDEA中無法正常使用readLine的解決方法,原因是由于Gradle的標(biāo)準(zhǔn)輸入默認(rèn)并不與系統(tǒng)標(biāo)準(zhǔn)輸入綁定,需手動設(shè)置,需要的朋友可以參考下2021-12-12
關(guān)于Java鎖性能提高(鎖升級)機制的總結(jié)
這篇文章主要介紹了關(guān)于Java鎖性能提高(鎖升級)機制的總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-05-05
在Java 8中將List轉(zhuǎn)換為Map對象方法
這篇文章主要介紹了在Java 8中將List轉(zhuǎn)換為Map對象方法,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下2018-11-11
Spring Cloud Gateway 默認(rèn)的filter功能和執(zhí)行順序介紹
這篇文章主要介紹了Spring Cloud Gateway 默認(rèn)的filter功能和執(zhí)行順序,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-10-10

