对于可能经常更改,或者可能大批量更改的业务场景。个人不推荐使用这种方式,因为会导致主键跳跃。每次存在(即更新)时,主键会+1,也就是说如果你的表里有100w数据,当你更改的时候,每调用一次下面的方法,主键+1。也可能出现其实你数据只有100w,结果主键已经到200w甚至更多了。
如果你还决定要用这种方式,可以往下看。
前提:判断更新或者插入的条件是 表里的唯一索引是否冲突,比如插入主键值相同的数据。
如需要根据某个键值来判断,必须创建唯一索引。
方式:使用 ON DUPLICATE KEY UPDATE 命令
Mybatis
<insert id="insertOrUpdate" parameterType="java.util.List" useGeneratedKeys="true"
keyProperty="id">
insert into user_agree_protocol(
id,
user_id,
protocol_id,
protocol_version
)
values
<foreach collection="list" item="item" index="index"
separator=",">
( #{item.id},
#{item.userId},
#{item.protocolId},
#{item.protocolVersion})
</foreach>
ON DUPLICATE KEY UPDATE
protocol_version = VALUES (protocol_version)
</insert>
SQL语句的写法和MyBatis写法差不多,就不单独给出了。这里用VALUES就可以直接拿到原本要插入但插入失败的值。
最后,本人还没有找到更合适的方法,只能把sql拆成了,select,insert和update拆成三条sql。不过压测了感觉效率也没有低很多。如果有小伙伴有更好的方法,还请不吝赐教。