Mybatis-Plus更新表字段为null

问题

业务上需要将一张表的一个字段从有值置为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);
    }
}
经验分享 程序员 微信小程序 职场和发展