不能随便的调用mybatisplus的update(对象)会导致全部进行更新,如果调用要小心设置DTO的参数进行避免null更新

网友投稿 369 2022-09-27

不能随便的调用mybatisplus的update(对象)会导致全部进行更新,如果调用要小心设置DTO的参数进行避免null更新

前言:今天业务那边发现调用只修改所属项目的单参数接口导致的一条数据里面的其他条数据进行清空了,导致下游获取不到数据,我查了查代码,一眼就发现有问题。

问题场景:

1、主要是调用了Mybatis的自带的update参数方法,这个是全量的更新类的参数,

场景复现:

同时写的代码:

@Override public void updateByNewsId(TbmNewsProcessing tbmNewsProcessing) { LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper(); lambdaQueryWrapper.eq(TbmNewsProcessing::getNewsId, tbmNewsProcessing.getNewsId()); processingMapper.update(tbmNewsProcessing, lambdaQueryWrapper); } @Override public void updateAppIds(String newsId, String appIds) { TbmNewsProcessing tbmNewsProcessing = new TbmNewsProcessing(); tbmNewsProcessing.setUpdateTime(LocalDateTime.now()); tbmNewsProcessing.setNewsId(Long.parseLong(newsId)); tbmNewsProcessing.setAppIds(appIds); tbmNewsProcessing.setDelReason("接口变更所属项目"); tbmNewsProcessing.setDelType(NewsDeleteTypeEnum.NINE.getType()); updateByNewsId(tbmNewsProcessing); }

调用的是

com.baomidou.mybatisplus.core.mapper;里面的自带有的方法:

运行的SQL如下

==>  Preparing: UPDATE  processing SET news_id=?, app_ids=?, trading_market=?, range_base=?, range_plus=?, financial=?, financial_plus=?, form=?, update_time=?, del_type=?, del_reason=?, sentiment=?, news_importance=? WHERE news_id = ?

==> Parameters: 1181793409217(Long), [2, 3, 5, 6, 7](String), null, null, null, null, null, null, 2020-12-08 13:35:07.968(Timestamp), 9(Integer), 接口变更所属项目(String), null, null, 1181793409217(Long)

<==    Updates: 1

会把其他参数的null进行更新update,导致的问题会很严重。会把其他参数直接的覆盖掉,导致运行之后其他参数置位空了。这个算是生产事故了!

2、解决办法:

1、update的入参为Object,这个对象的所有参数是数据库里面最新的数据,可以直接调用这个Mapper的update;

比如我使用的方法体是:

tbmNewsProcessingDao.updateByNewsId(tbmNewsProcessing);

@Overridepublic void updateByNewsId(TbmNewsProcessing tbmNewsProcessing) { LambdaQueryWrapper lambdaQueryWrapper = new LambdaQueryWrapper(); lambdaQueryWrapper.eq(TbmNewsProcessing::getNewsId, tbmNewsProcessing.getNewsId()); processingMapper.update(tbmNewsProcessing, lambdaQueryWrapper);}

入参是整体一个对象;

2、单独的写一条update数据进行操作单个字段也是可以的!

/*** * 获取状态和所属项目 * @param newsId * @return */@Update("update tbm_news_processing t set t.identified=1 where t.news_id=#{newsId}")int updateIdentified(@Param("newsId") Long newsId);

3、如果全部参数执行那么需要小心设置字段避免被全局更新;实体类的字段不允许有注释:

字段允许为null (例如时间,有参数要置空允许update,实体类上可以加上这个注解) @TableField(strategy=FieldStrategy.IGNORED)

不添加这个注解的时候,那么null是不会update的。如果添加了这个注解,那么这个null参数,也会update的。这个特别容易修改。一旦修改会造成很大的麻烦,而且不容易发现!!!!

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java如何实现字符串每隔4位加空格
下一篇:Java-单机版的书店管理系统(练习设计模块和思想_系列汇总)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~