Mybatis-Plus中update()和updateById()将字段更新为null

目录
  • 简介
  • 问题描述
  • 原因
    • 概述
    • 源码分析
  • 所有策略
  • 设置为null的方案
    • 方案1:使用UpdateWrapper更新
    • 方案2:设置全局的field-strategy(不推荐)
    • 方案3:设置某个字段的field-strategy
  • 参考文章

简介

说明

本文介绍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内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • Mybatis-Plus使用updateById()、update()将字段更新为null

    目录 问题背景 问题原因 解决方案 问题背景 昨晚同事找我帮他看一个问题,他使用mybatis-plus中提供的updateById方法,想将查询结果中某个字段原本不为null的值更新为null(数据库设计允许为null),但结果该字段更新失败,执行更新方法后还是查询的结果. 问题原因 mybatis-plus FieldStrategy 有三种策略: IGNORED:0 忽略 NOT_NULL:1 非 NULL,默认策略 NOT_EMPTY:2 非空 而默认更新策略是NOT_NULL:非 NU

  • Mybatis-Plus中update()和updateById()将字段更新为null

    目录 简介 问题描述 原因 概述 源码分析 所有策略 设置为null的方案 方案1:使用UpdateWrapper更新 方案2:设置全局的field-strategy(不推荐) 方案3:设置某个字段的field-strategy 参考文章 简介 说明 本文介绍Mybatis-Plus无法将字段更新为null的原因及解决方法. 问题描述 用Mybatis-Plus的update()或者updateById()来更新数据时,无法将字段设置为null值(更新后数据还是原来的值). 原因 概述 默认情况

  • mysql中update按照多重条件进行更新处理的方案

    目录 1.场景问题说明 2.处理方案 2.1 使用update case when 2.2 使用if标签 总结 1.场景问题说明 mysql中一般的update写法支持的方式是,update 表 set 字段名=修改后的字段值 where 条件1 and 条件2 and 其他条件;如果现在需求是对满足where后面的条件基础之上需对满足指定的条件数据再进行不同更新处理,那应该如何处理?如果有这样的疑问或是遇到此类场景请继续往下看. 还原一下我遇到的业务场景:现有一批会员卡,会员卡类型有次数卡和期

  • MybatisPlus 不修改全局策略和字段注解如何将字段更新为null

    mybatis-plus 以下简称mp,目前应该也算是主流的一款数据访问层应用框架.源于其对mybatis 的近乎完美的封装,让我们在使用的时候无比的顺滑, 几乎提供了所有单表操作的方法,大大提升了效率.并且这款框架还是国产的哦,没了解过的可以去了解一下. 回归正题,我们这次来讲一下,怎么样通过mp将数据库中的一个字段更新为null. 可能很多人会觉得奇怪,更新为null, 直接set field = null 不就可以了.这里大家要注意一下,一般情况,我们在使用mp的时候,他的默认策略是空不更

  • JPA save()方法将字段更新为null的解决方案

    这篇文章主要介绍了JPA save()方法将字段更新为null的解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 今天在开发上碰到一个问题,在做页面展示的时候传给前端十个字段,前端修改了其中3个的值,所以只传了3个值给后端,其余字段默认为null,更新后其他7个字段在全部变为了空值. 在前端没法全量回传所有属性的前提下,由后端来处理这类问题. 解决方法: 1.写一个工具方法(UpdateUtil) 用来筛选出所有的空值字段 2.更新时先通

  • MySQL中可为空的字段设置为NULL还是NOT NULL

    经常用mysql的人可能会遇到下面几种情况: 1.我字段类型是not null,为什么我可以插入空值 2.为什么not null的效率比null高 3.判断字段不为空的时候,到底要用 select * from table where column <> '' 还是要用 select * from table where column is not null 带着上面几个疑问,我们来简单的研究一下null 和 not null 到底有什么不一样,他们之间的区别是什么以及各自的效率问题. 首先,

  • Postgres中UPDATE更新语句源码分析

    目录 PG中UPDATE源码分析 整体流程分析 解析部分——生成语法解析树UpdateStmt 解析部分——生成查询树Query 优化器——生成执行计划 执行器 事务 总结 PG中UPDATE源码分析 本文主要描述SQL中UPDATE语句的源码分析,代码为PG13.3版本. 整体流程分析 以update dtea set id = 1;这条最简单的Update语句进行源码分析(dtea不是分区表,不考虑并行等,没有建立任何索引),帮助我们理解update的大致流程. SQL流程如下: parse

  • mybatis update set 多个字段实例

    我就废话不多说了,大家还是直接看代码吧~ <update id="updateCustomer" parameterType="com.entrym.domain.Customer"> UPDATE customer set <if test="name!=null">name=#{name,jdbcType=VARCHAR},</if> <if test="role!=null"&g

  • 利用Mybatis向PostgreSQL中插入并查询JSON字段

    目录 应用场景介绍 数据insert 数据select BATCH 批量插入 前言: 这里我使用的是TimescaleDB,加了一个时间戳字段,不过没差.关于PostgreSQL中Json数据类型的操作,可以参考官网. 应用场景介绍 将TCP发过来的数据包(通过消息队列发过来)解析出数据(一个数据包含有多帧,一帧中含有多条信息),并和本地规则表的格式对应起来.以JsonLineMsg实体类代表对应的一帧数据: package tsdb.entity; import lombok.AllArgsC

  • Mybatis和orcale update语句中接收参数为对象的实例代码

    Mybatis的 mapper.xml 中 update 语句使用 if 标签判断对像属性是否为空值. UserDTO是传过来参数的类型,userDTO是在mapperDao接口中给更新方法的参数起的别名. mapperDao.java int updata(@Param("userDTO") UserDTO userDTO); mapper.xml <update id="updata" parameterType="UserDTO"&g

随机推荐