MyBatis-Plus updateById更新不了空字符串或null的解决方法
作者:super先生
1. 文章引言
在开发的过程中,我们经常使用MyBatis-Plus
的updateById
方法更新数据表,但今天在更新appConfig
表时,发现无法将content
字段更新为null
。
如下是我的测试代码:
@Test public void testUpdateById() { Long id = 10L; AppConfig beforeAppConfig = appConfigService.getById(id); System.out.println("输出更新 前 的应用配置内容:" + beforeAppConfig.getContent()); System.out.println(); // 将 id = 10的应用配置的内容修改 null beforeAppConfig.setContent(null); appConfigService.updateById(beforeAppConfig); // 查询更新的 id = 10的应用配置的内容 AppConfig afterAppConfig = appConfigService.getById(id); System.out.println("输出更新 后 的应用配置内容:"+afterAppConfig.getContent()); }
输出结果如下图所示:
由上图可知,更新前后输出的内容不变。
换句话说,上述此代码 beforeAppConfig.setContent(null);
虽然设置content
为null
,但数据库并没有将content
更新为null
。
这是什么原因呢?
2. 分析问题
想要搞清楚没有将content
更新为null
原因,我们不妨看看上图中的用绿色框圈出来的MyBatis-Plus
打印出的mysql
语句,如下所示:
UPDATE app_config SET create_time=? WHERE id=?
你会清楚地看到,mysql
语句中没有content
字段。
按照预期结果,MyBatis-Plus
打印出的mysql
语句应该如下:
UPDATE app_config SET create_time=?, content=? WHERE id=?
为什么MyBatis-Plus
没有按预期打印出的mysql
语句,经过查找资料可得。
其实是MyBatis-Plus
对字段的验证策略导致的,MyBatis-Plus
默认进行了不是全量更新的策略。
查阅官网发现有一个属性,而我的application.yml
没有配置这个属性,如下代码所示:
#mybatis配置 mybatis-plus: mapper-locations: classpath*:/mapper/*Mapper.xml type-aliases-package: com.superjson.superjsonmanager.mapper configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl # 按下划线转驼峰规则映射数据库字段与java bean属性之间的关系 map-underscore-to-camel-case: true # 关闭一级缓存 # local-cache-scope: statement # 关闭二级缓存 # cache-enabled: false global-config: db-config: id-type: auto logic-delete-value: -1 logic-not-delete-value: 0
如果没有配置这个属性,那么,MyBatis-Plus
采用了默认的字段验证策略。
这个属性就是field-strategy
,在原application.yml
中加入该属性,如下代码所示:
global-config: #字段策略 0:忽略判断,1:非NULL判断,2:非空判断 field-strategy: 1 db-config: id-type: auto logic-delete-value: -1 logic-not-delete-value: 0
field-strategy
字段更新插入策略属性说明:
IGNORED(0)
: “忽略判断”, 所有字段都更新和插入NOT_NULL(1)
:“非 NULL 判断”, 只更新和插入非NULL
值NOT_EMPTY(2)
:“非空判断”,只更新和插入非NULL
值且非空字符串
field-strategy
默认策略是NOT_NULL(1)
,即更新的时候做了null
判断,默认不更新为null
的传参。
3. 解决问题
既然知道了问题所在,便可以通过如下三种方式解决。
3.1 方法1:全局配置方式
在MyBatis-Plus
配置文件中修改field-strategy
字段验证的值为0
,即忽略判断,如下代码所示:
global-config: #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断" field-strategy: 0 db-config: id-type: auto logic-delete-value: -1 logic-not-delete-value: 0
如是配置后,并参照网上说的,在PO
对象(即@TableField(value="content"
)修饰字段的时候,还需要加入el
属性,但我是新版本的MyBatis-Plus
,已经不支持el
属性了,如下源码所说:
我虽然在content
对象上加上update
属性,如下代码所示:
/** 配置内容 */ @TableField(value = "content",update = "null" ) private String content;
仍无法将content
字段修改为null
,如下图所示:
如果有知道的,可以在评论区中留言,不胜感激。
此外,如果你的MyBatis-Plus
版本支持el
。你在设置了 field-strategy: 0
的前提下,同时你已确保了你的PO
对象(即@TableField(value="XSID")
修饰字段加入了el
属性 (每个属性对应数据库的jdbcType类型,这样才能成功更新空值或null),如下图:
你可以采用el
的这种方式修改。
3.2 方法2:非null字段验证策略
配置完成后,测试类修改完成,并重新启动,如下图所示:
此时,你会发现可以更新空字符串' '
,如下图所示:
但是一些比如Date
等对象类型的设置空是要设置为null
的,你会发现一样更新不了null
。
3.3 方法3:通过注解的方式
由于表中的字段基本上都是varchar
字符类型的,所以此时可以在PO
中对类型为对象类型的属性,通过注解对对象类型的属性单独设置字段验证策略为IGNORED
,如下代码所示:
/** 配置内容 */ @TableField(value = "content",updateStrategy = FieldStrategy.IGNORED) private String content;
同时修改测试代码,如下图所示:
这样就可以成功更新值为null
或者空字符串' '
了,问题解决,如下图所示:
如果你的MyBatis-Plus
版本和我的版本不同,你可能是下图中的注解,同样能解决问题。
4. 总结
到此这篇关于MyBatis-Plus updateById更新不了空字符串或null的解决方法的文章就介绍到这了,更多相关MyBatis-Plus updateById更新 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!