在生产中,经常会有同学喜欢使用一条SQL语句执行更新/插入操作(解决唯一键冲突)。
比如下面的例子:利用唯一键:(code, name) 更新学生表的学号和姓名。
-
当唯一键存在时,就会更新,当不存在时就会插入数据。
<insert id="replaceBatch" parameterType="java.util.List">
replace into student(code, name, address,)
VALUES
<foreach collection="list" item="it" separator=",">
(#{it.code},#{it.name},#{it.address})
</foreach>
</insert>
注意:replace into 的工作原理 1、如果原来的数据存在,就删除这条数据,重新插入一条数据 2、如果原来的数据不存在,就插入一条新数据。
对主从同步的影响: MySQL 8.0 之前,主库使用 replace into ,当原来的数据存在,主库会删除这条数据,重新插入一条数据。
但是MySQL会将其优化成:从库在原来的数据上进行更新,这样就会导致主从库主键 id 不一致。
当然如果不使用主键,replace into 还是没有影响的。
其他解决唯一键冲突的方式
ignore 关键字
insert ignore into table student (code, name) values (2021, "turato"); 作用:当存在该条记录时,就忽略,如果不存在才插入。
on duplicate key update
当发生唯一键冲突时,修改记录的内容,否则就插入数据。
比如:唯一键是 code-name
<insert id="batchInsert"
parameterType="java.util.List">
<foreach collection="list" item="item" index="index" open="" close="" separator=";">
insert into student (code, name, address,)
values
(#{item.code,jdbcType=VARCHAR},
#{item.name,jdbcType=INTEGER},
#{item.address,jdbcType=VARCHAR},
on duplicate key
update
code = #{item.code,jdbcType=VARCHAR},
name = #{item.name,jdbcType=VARCHAR},
address = #{item.address,jdbcType=VARCHAR},
</foreach>
</insert>