前一段做一个批量更新的需求,数据的来源是一个Excel文件,列有值的话,就更新,没值的话,就忽略。
首先可以使用mybatis-plus的com.baomidou.mybatisplus.extension.service包下的IService接口里面的批量方法
但它的实现原理是伪批量,所以我参照系统中之前的批量更新写法,写了一个Mysql自带的批量更新,Map.xml中的代码如下:
UPDATE product_online
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.productName,jdbcType=VARCHAR}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.productSpecific,jdbcType=VARCHAR}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.productUnit,jdbcType=VARCHAR}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.weight,jdbcType=DECIMAL}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.originPlace,jdbcType=VARCHAR}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.shelfLife,jdbcType=VARCHAR}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.productBrief,jdbcType=VARCHAR}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.storageType,jdbcType=VARCHAR}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.isReturn,jdbcType=TINYINT}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.subTitle,jdbcType=VARCHAR}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.keywords,jdbcType=VARCHAR}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.updatedTime}
when product_code = #{item.productCode,jdbcType=VARCHAR} then #{item.updatedBy,jdbcType=VARCHAR}
product_code = #{item.productCode,jdbcType=VARCHAR}
但这种方式有两个大坑!!
1号坑:使用 case when then end语句 批量更新时,where条件是必须的,不然默认会更新所有的,把原值覆盖成数据库类型的默认值!!
2号坑:我的数据来源是一个Excel文件,比如说Excel文件中共100行数据,其中只要有一行数据 在第3列有值,那么批量更新的时候,这100行数据的第3列都必须得有值,不然的话,数据库会把其他第3列的值覆盖成数据库类型的默认值!!
鉴于这两个坑的存在,我在批量更新前,就必须得先去数据库中查,得到查询结果的List,然后对每个列进行非空检验,如果为空,就把数据库中的值赋给该列,这样就可以避免 误操作篡改数据了。
这个功能上线后,我心里还是很忐忑的,必经update操作一定要谨慎,但最近观察一段时间的使用后,生产上没出现数据问题,哈哈