首页 > 其他分享 >Mybatis-Plus中updateById方法不能更新空值问题

Mybatis-Plus中updateById方法不能更新空值问题

时间:2022-12-07 17:35:13浏览次数:40  
标签:updateById private User 空值 字段 Plus 更新 Mybatis user


问题描述

在Mybatis-Plus中调用updateById方法进行数据更新默认情况下是不能更新空值字段的。而在实际开发过程中,往往会遇到需要将字段值更新为空值的情况。
那么如果让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());
}

执行结果:

Mybatis-Plus中updateById方法不能更新空值问题_mybatis-plus


可以看到由于email字段的值为null,所以执行updateById方法时没有对email字段进行更新。


原因分析:

Mybatis-Plus中字段的更新策略是通过FieldStrategy属性控制的。

在实体字段上,如果不通过​​@TableField​​​注解指定字段的更新策略,字段默认的更新策略是​​FieldStrategy.DEFAULT​​,即跟随全局策略。

而Mybatis-Plus的全局配置中,字段的默认更新策略是​​FieldStrategy.NOT_NULL​​,即进行空值判断,不对NULL值数据进行处理。

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;
}

相关文档:
​Mybatis-Plus中FieldStrategy说明

​​Mybatis-Plus字段策略FieldStrategy详解​​

Tip⚠️:
官网链接,自力更生。


解决方案:

1、设置字段级别的更新策略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;
}

再次执行上面的单元测试:

Mybatis-Plus中updateById方法不能更新空值问题_mybatis-plus_02


email字段虽然是空值,但仍然进行了更新操作,说明此时email字段已经支持空值更新。

2、设置全局更新策略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());
}

执行结果:

Mybatis-Plus中updateById方法不能更新空值问题_updateById_03


age和email字段都支持空值更新,说明全局更新策略​​ignored​​生效。

3、采用alwaysUpdateSomeColumnById方法进行全字段更新

Mybatis-Plus中自带的扩展方法​​alwaysUpdateSomeColumnById​​​会忽略字段的更新策略,直接对实体中的每一个字段都执行更新操作。
如果你不想修改全局的字段更新策略,又需要项目中某个实体的所有字段都支持空值更新,推荐采用该方法。
该方式的控制级别是​​​实体级别的控制​​。

实现步骤:
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());
}

执行结果:

Mybatis-Plus中updateById方法不能更新空值问题_updateById_04


虽然没有修改Mybatis-Plus全局的更新策略,也没有在实体字段上使用@TableField注解修改字段的更新策略,但是​​alwaysUpdateSomeColumnById​​方法仍然可以对空值字段进行更新。

小结:

本文主要是对Mybatis-Plus中updateById方法不能更新空值问题进行了分析说明,并提供了3种解决方案。

  1. 字段级别解决方案
    采用​​​@TableField​​​注解修改字段默认的更新策略为​​FieldStrategy.IGNORED​​。
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String email;
  1. 实体级别解决方案
    调用Mybatis-Plus中的扩展方法​​alwaysUpdateSomeColumnById​​,忽略字段更新策略,直接对实体中所有字端进行更新。
  2. 全局级别解决方案
    修改Mybatis-Plus的全局更新策略为​​ignored​
mybatis-plus.global-config.db-config.update-strategy=ignored


标签:updateById,private,User,空值,字段,Plus,更新,Mybatis,user
From: https://blog.51cto.com/u_15905482/5919838

相关文章