批量插入,存在则更新,不存在则插入:ON DUPLICATE KEY UPDATE

语法:insert into t_user_1 values(11,'王五',13),(9,'王五1111',13),(5,'王五111',13),(6,'王五1111',23) ON DUPLICATE KEY UPDATE  name = VALUES(name) ,age = VALUES(age)

需求:插入设备,device_id为雪花算法主键id,device_code为唯一索引,批量插入多条device ,device_code存在的跟新,不存在的添加

落地实现:

 <insert id="onDuplicateKeyUpdate">
        insert into aiot_device(device_code,tenant_id,is_online,channel_num,
        device_info,product_type,edge_host_id,device_id)
        values
            <foreach collection="devices" separator="," item="device">
                (#{device.deviceCode},#{device.tenantId},#{device.isOnline},
                 #{device.channelNum},#{device.deviceInfo},
                #{device.productType},#{device.edgeHostId},#{device.deviceId})
            </foreach>
        on duplicate key update
             tenant_id=values(tenant_id),
             is_online=values(is_online),
             channel_num=values(channel_num),
             device_info=values(device_info),
             product_type=values(product_type),
             edge_host_id=values(edge_host_id),
             device_id=values(device_id)
    </insert>

//测试代码 因为批量添加,且是自己写的sql MP没有自动添加雪花算法主键,这里自行手动添加 IdWorker.getIdStr()

 /**
     * 获得 Camera 列表
     *
     * @author xzj
     * @since 2022-05-07
     */
    @GetMapping("/1")
    public Result list1() {
        List<Device> list = new ArrayList<>();
        list.add(new Device().setDeviceCode("1").setIsOnline("0").setDeviceInfo("aaaaa").setDeviceId(IdWorker.getIdStr()));
        list.add(new Device().setDeviceCode("2").setIsOnline("0").setDeviceInfo("bbbbb").setDeviceId(IdWorker.getIdStr()));
        list.add(new Device().setDeviceCode("5").setIsOnline("0").setDeviceInfo("ccccc").setDeviceId(IdWorker.getIdStr()));
        deviceMapper.onDuplicateKeyUpdate(list);
        return Result.success();
    }

弊端:每次会把device_id覆盖成新的id,可是不填device_id没办法插入表,因为数据库device_id是varchar类型

增加ifnull判断解决 device_id=ifnull(device_id,values(device_id))    表示有值更新成原来的值

   <insert id="onDuplicateKeyUpdate">
        insert into aiot_device(device_code,tenant_id,is_online,channel_num,
device_info,product_type,edge_host_id,device_id)
        values
            <foreach collection="devices" separator="," item="device">
                (#{device.deviceCode},#{device.tenantId},#{device.isOnline},
                 #{device.channelNum},#{device.deviceInfo},
                #{device.productType},#{device.edgeHostId},#{device.deviceId})
            </foreach>
        on duplicate key update
             tenant_id=values(tenant_id),
             is_online=values(is_online),
             channel_num=values(channel_num),
             device_info=values(device_info),
             product_type=values(product_type),
             edge_host_id=values(edge_host_id),
             device_id=ifnull(device_id,values(device_id))
    </insert>

 

posted @ 2022-04-18 20:19  java架构师1  阅读(683)  评论(0)    收藏  举报