首頁 > 軟體

Mybatis-Plus中update()和updateById()將欄位更新為null

2022-08-09 18:00:30

簡介

說明

本文介紹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內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com