首页 > 其他分享 >Mybatis-Plus无法将字段更新为null的原因及解决方法。

Mybatis-Plus无法将字段更新为null的原因及解决方法。

时间:2023-02-19 23:45:48浏览次数:52  
标签:NULL column columnProperty Plus user FieldStrategy Mybatis 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)可能会影响其他业务。

        所以,此方法也不推荐。 

标签:NULL,column,columnProperty,Plus,user,FieldStrategy,Mybatis,null
From: https://www.cnblogs.com/brandon-i/p/17135953.html

相关文章

  • maven 自动生成mybatis代码
    <!--dependency和plugin中jar的版本根据自己需求选择,但同一个jar版本要保持一致--><!--配置在dependencies中--><dependency><groupId>org.mybatis.gener......
  • mybatis操作数据库
    mybatis介绍mybatis不会对应用程序或者数据库的现有设计强加任何影响。sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。mybatis结构操......
  • 10.MyBatis-Plus的使用
    整合MyBatis-Plus导入依赖在解决逆向工程生成的代码报错时候已经给bianen-common导入了依赖导入数据库的驱动导入驱动和MySql的版本有关,我安装的MySql版本是5.7.36打......
  • MyBatis面试题
    MyBatis面试题1、什么是Mybatis?1、Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接......
  • sqlit 自增id为null
    CREATETABLEproejct(idUNSIGNEDINTEGERAUTO_INCREMENT,nameVARCHAR(50)NOTNULL,typeCHAR(10)NOTNULL,PRIMARYKEY(id))以上是表的定义,不知道为......
  • element-plus实现table表格序号递增的效果
    element-plus组件排序,可以给序号行加一个type="index"就可以实现按序号排序效果,但是当页码到第二页时,又是从一开始排列了。想要实现的效果是翻页后页码接上一页的顺序......
  • 使用ThreadLocal+OpenSessionInView优化Mybatis使用
    使用一个名为OpenSessionInView的servlet过滤器,简化在服务中使用mybatis的操作。   一、情况分析Mybatis的使用过程:1、获取配置文件2、获取session工厂......
  • springboot mybatis (关联关系:一对一,一对多,多对多)
    例如这个学生选课的这个:这个里面课程跟老师是1对1的,而老师对课程是1对多的,一个课程只能由一个老师教,而一个老师可以教多个课程对于学生和课程之间是多对多的,一个学生可以......
  • 版本不兼容(NoSuchMethodError: com.baomidou.mybatisplus.core.toolkit.StringUtils.i
    "C:\ProgramFiles\Java\jdk1.8.0_221\bin\java.exe"-XX:TieredStopAtLevel=1-noverify-Dspring.output.ansi.enabled=always-Dcom.sun.management.jmxremote-Dsprin......
  • mybatis中#{}和${}有什么区别
    {}是预编译处理,是占位符;${}是字符串替换、是拼接符。mybatis在处理#{}时,会将sql中的#{}替换为?,调用PreparedStatement来赋值,可以有效防止SQL注入。在处理${}时,就是简单将$......