问题
业务上需要将一张表的一个字段从有值置为null,使用mybatis-plus(版本号为3.3.0)的updateById() 方法成功但数据库数据未修改,控制台打印的sql也没有对字段belong_type更新
/**
* 使用 boolean updateById(T entity);
* @param typeId
* @return
*/
public boolean removeType(Integer typeId) {
ChannelType channelType = getById(typeId);
channelType.setBelongType(null);
return updateById(channelType);
}
UPDATE channel_type SET type_name=?, type_code=?, is_received=?, is_system_type=?, data_source=?, create_time=? WHERE id=? AND delete_flag=0
Parameters: 2(String), 2(String), 1(Integer), 0(Integer), 2(String), 2021-03-23 00:00:00.0(Timestamp), 25(Integer)
分析
mybatis-plus在更新操作的时候,对null值的设置默认不采用。
具体原因:mybatis-plus中有一个枚举类FieldStrategy 如下
package com.baomidou.mybatisplus.annotation;
public enum FieldStrategy {
IGNORED,
NOT_NULL,
NOT_EMPTY,
DEFAULT,
NEVER;
private FieldStrategy() {
}
}
mybatis-plus默认更新策略是NOT_NULL,这个默认策略导致了更新null值失效。
解决方案
1. 修改配置
并不推荐修改配置,可能会对其他业务造成影响,所以推荐针对当前业务逻辑进行更新
2. 使用UpdateWrapper方式更新
方法修改:
/**
* 使用 UpdateWrapper
* @param typeId
* @return
*/
public boolean removeType(Integer typeId) {
UpdateWrapper uw = new UpdateWrapper();
uw.set(DBConstants.BELONG_TYPE, null);
uw.eq(DBConstants.ID, typeId);
return update(uw);
}
执行sql:
Preparing: UPDATE channel_type SET belong_type=? WHERE delete_flag=0 AND (id = ?)
==> Parameters: null, 25(Integer)
IService层方法:
public interface IService<T>{
...
boolean update(T entity, Wrapper<T> updateWrapper);
default boolean update(Wrapper<T> updateWrapper) {
return update(null, updateWrapper);
}
}