You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 11:20:55