MyBatis批量Upsert:如何避免Null值覆盖已存数据
解决MyBatis批量Upsert避免Null覆盖原有字段的问题
用MySQL条件函数实现非Null字段才更新
不用在MyBatis里写<if>标签判断,直接在ON DUPLICATE KEY UPDATE段利用MySQL的IF()函数做字段非Null校验,就能实现只有插入值不为Null时才覆盖原有字段,否则保留原值。
修改后的映射器代码:
<insert id="batchUpsert" keyProperty="id" keyColumn="id" parameterType="java.util.List"> INSERT INTO pkg_table (col1, col2, col3) VALUES <foreach item="item" collection="list" separator=","> (#{item.col1}, #{item.col2}, #{item.col3}) </foreach> ON DUPLICATE KEY UPDATE `col1` = IF(VALUES(col1) IS NOT NULL, VALUES(col1), col1), `col2` = IF(VALUES(col2) IS NOT NULL, VALUES(col2), col2), `col3` = IF(VALUES(col3) IS NOT NULL, VALUES(col3), col3) </insert>
逻辑说明
VALUES(col1)会获取当前批量插入中对应行的col1字段值IF(VALUES(col1) IS NOT NULL, VALUES(col1), col1)的逻辑是:如果插入的col1不为Null,就用插入值更新;否则保留原字段的现有值- 这种方式完全在数据库层面处理逻辑,避开了
ON DUPLICATE KEY UPDATE无法访问foreach中item变量的问题,同时适配批量插入的每条记录独立判断需求
补充提示
原代码中parameterType设置为com.mycompany.entity.PackageDO有误,批量插入的参数应为集合类型,这里改成java.util.List(MyBatis 3.5+也可以省略该属性,框架会自动识别)。
内容的提问来源于stack exchange,提问作者uncle bob
相关产品推荐
相关产品推荐

