场景
业务中某些需求,需要将某个字段设为null。
但是mybatisplus并不会更新为null的字段。
这是因为mybatisplus的更新策略默认为NOT_EMPTY,源码中可以查看。
package com.baomidou.mybatisplus.annotation;
/**
* 字段策略枚举类
* <p>
* 如果字段是基本数据类型则最终效果等同于 {@link #IGNORED}
*
* @author hubin
* @since 2016-09-09
*/
public enum FieldStrategy {
/**
* 忽略判断
*/
IGNORED,
/**
* 非NULL判断
*/
NOT_NULL,
/**
* 非空判断(只对字符串类型字段,其他类型字段依然为非NULL判断)
*/
NOT_EMPTY,
/**
* 默认的,一般只用于注解里
* <p>1. 在全局里代表 NOT_NULL</p>
* <p>2. 在注解里代表 跟随全局</p>
*/
DEFAULT,
/**
* 不加入 SQL
*/
NEVER
}
解决方法1
在字段头上加注释,设定局部更新策略。
@TableField(updateStrategy = FieldStrategy.IGNORED)
private String stdRegister;
但该方法有一个问题。如果其他接口使用该类时,也没有传该字段参数,那么其他接口会把原来的字段都更新为null,造成原来数据丢失,所以不推荐用这种方法。
解决方法2
用update+updatewrapper可实现,关键还是wrapper中将字段设置为null,如果wrapper没有set为null,则这种方式还是会失败。
UpdateWrapper<StudentMsg> wrapper = new UpdateWrapper<>();
wrapper.eq("std_id", std.getStdId());
wrapper.set("std_register", null);
return this.update(wrapper);
如果还有其他字段需要更新,update方法还可以传入entity,将需要set为null的字段写在wrapper中。
UpdateWrapper<StudentMsg> wrapper = new UpdateWrapper<>();
wrapper.eq("std_id", std.getStdId());
wrapper.set("std_register", null);
return this.update(std, wrapper);
这种方式实际执行的sql是,wrapper会覆盖前边的entity
UPDATE
std_mes
SET
std_name='阿里',
std_gender='男',
std_age=10,
std_register='浙江杭州',
std_register=null
WHERE
(
std_id = 0
);
解决方法3
用mapper写sql实现
<update id="setRegisterNull">
update std_mes set std_register = null where std_id = #{id};
</update>