Mybatis-Plus中update()和updateById()將字段更新為null

簡介

說明

本文介紹Mybatis-Plus無法將字段更新為null的原因及解決方法。

問題描述

用Mybatis-Plus的update()或者updateById()來更新數據時,無法將字段設置為null值(更新後數據還是原來的值)。

原因

概述

默認情況下,Mybatis-Plus在更新時會判斷字段是否為null,如果是null,則不設值(不將這個字段拼接為SQL的SET語句)。

源碼分析

字段策略的源碼:com.baomidou.mybatisplus.annotation.FieldStrategy

package com.baomidou.mybatisplus.annotation;
 
/**
 * 字段策略枚舉類
 */
public enum FieldStrategy {
    /**
     * 忽略判斷
     */
    IGNORED,
    
    /**
     * 非NULL判斷
     */
    NOT_NULL,
    
    /**
     * 非空判斷(隻對字符串類型字段,其他類型字段依然為非NULL判斷)
     */
    NOT_EMPTY,
    
    /**
     * 默認的,一般隻用於註解裡
     * <p>1. 在全局裡代表 NOT_NULL</p>
     * <p>2. 在註解裡代表 跟隨全局</p>
     */
    DEFAULT,
    
    /**
     * 不加入 SQL
     */
    NEVER
}

可以看到,FieldStrategy.DEFAULT:默認等於FieldStrategy.NOT_NULL,也就是:字段不為Null時才拼接SQL。 

所有策略

實際上,Mybatis-Plus在增刪改查時默認對Null等情況都進行瞭判斷。

源碼裡的註釋已經很清楚瞭,本處不再贅述。源碼位置:com.baomidou.mybatisplus.annotation.TableField

package com.baomidou.mybatisplus.annotation;
 
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import org.apache.ibatis.type.UnknownTypeHandler;
 
import java.lang.annotation.*;
 
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE})
public @interface TableField {
 
    // 其他代碼
 
    /**
     * 字段驗證策略之 insert: 當insert操作時,該字段拼接insert語句時的策略
     * <p>
     * IGNORED: 直接拼接 insert into table_a(column) values (#{columnProperty});
     * NOT_NULL: insert into table_a(<if test="columnProperty != null">column</if>) values (<if test="columnProperty != null">#{columnProperty}</if>)
     * NOT_EMPTY: insert into table_a(<if test="columnProperty != null and columnProperty!=''">column</if>) values (<if test="columnProperty != null and columnProperty!=''">#{columnProperty}</if>)
     * NOT_EMPTY 如果針對的是非 CharSequence 類型的字段則效果等於 NOT_NULL
     *
     * @since 3.1.2
     */
    FieldStrategy insertStrategy() default FieldStrategy.DEFAULT;
 
    /**
     * 字段驗證策略之 update: 當更新操作時,該字段拼接set語句時的策略
     * <p>
     * IGNORED: 直接拼接 update table_a set column=#{columnProperty}, 屬性為null/空string都會被set進去
     * NOT_NULL: update table_a set <if test="columnProperty != null">column=#{columnProperty}</if>
     * NOT_EMPTY: update table_a set <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
     * NOT_EMPTY 如果針對的是非 CharSequence 類型的字段則效果等於 NOT_NULL
     *
     * @since 3.1.2
     */
    FieldStrategy updateStrategy() default FieldStrategy.DEFAULT;
 
    /**
     * 字段驗證策略之 where: 表示該字段在拼接where條件時的策略
     * <p>
     * IGNORED: 直接拼接 column=#{columnProperty}
     * NOT_NULL: <if test="columnProperty != null">column=#{columnProperty}</if>
     * NOT_EMPTY: <if test="columnProperty != null and columnProperty!=''">column=#{columnProperty}</if>
     * NOT_EMPTY 如果針對的是非 CharSequence 類型的字段則效果等於 NOT_NULL
     *
     * @since 3.1.2
     */
    FieldStrategy whereStrategy() default FieldStrategy.DEFAULT;
}

設置為null的方案

需求:根據用戶id,設置userName(用戶名),並將nickName(昵稱)設置為null。

方案1:使用UpdateWrapper更新

@Autowired
private UserService userService;
 
@ApiOperation("修改")
@PostMapping("/edit")
public void edit(User user) {
    userService.lambdaUpdate()
            .eq(User::getId, user.getId())
            .set(User::getUserName, user.getUserName())
            .set(User::getNickName, null)
            .update();
}

方案2:設置全局的field-strategy(不推薦)

application.yml

mybatis-plus:
  global-config:
      # 字段策略 0:忽略判斷,直接拼SQL, 1:非NULL, 2:非空,3:默認;4:永遠不加入SQL
    field-strategy: 0

註意

這是全局配置,會對所有的字段都忽略判斷,如果一些字段不想要修改,但是傳值的時候沒有傳遞過來,就會被更新為null,可能會影響其他業務數據的正確性。 

所以,盡量不要用此法。

方案3:設置某個字段的field-strategy

方法

隻在需要更新為null的字段上,設置忽略策略,如下:

/**
 * 昵稱
 */
@TableField(strategy = FieldStrategy.IGNORED)
private String nickName;

更新的方法:

@Autowired
private UserService;
 
@ApiOperation("修改")
@PostMapping("/edit")
public void edit(Long id) {
    User user = new User();
    user.setId(id);
    user.setNickName(null);
 
    userService.lambdaUpdate()
            .eq(User::getId, user.getId())
            .update(user);
}

註意

不同的業務對字段的需求可能不一樣,將字段指定為忽略判斷(直接拼SQL)可能會影響其他業務。

所以,此方法也不推薦。 

參考文章

【Mybatis-Plus】使用updateById()、update()將字段更新為null

mybatis-plus更新字段的時候設置為null,忽略實體null判斷

到此這篇關於Mybatis-Plus中update()和updateById()將字段更新為null的文章就介紹到這瞭,更多相關Mybatis-Plus 字段更新為null內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: