这篇文章主要介绍在Mybatis的INSERT语句中批量高效更新数据的方法,主要运用唯一索引配合DUPLICATE实现这个功能。应用场景是在执行INSERT语句时候,唯一索引所在字段的数据在数据表中已经存在,此时需要批量更新表中除唯一字段以外的所有字段为新数据。
本来没打算写这篇文章的,主要是因为网上DUPLICATE批量更新的文章几乎全部雷同,而且都是无效的,所以打算写一篇DUPLICATE批量更新的原创文章。不明白网上这么多无效的文章,为什么还有一堆人互相抄袭???
直接开门见山的上代码了:
<insert id="batchInsert" parameterType="java.util.List">
INSERT INTO op_clue_model_rule (rule_name, type, sql_str, rule_status, table_desc_list,
gmt_create_user, gmt_modified, gmt_modified_user, is_delete, remark)
VALUES
<foreach collection="list" item="item" index="index" separator=",">
(#{item.ruleName,jdbcType=VARCHAR}, #{item.type,jdbcType=TINYINT},
#{item.sqlStr,jdbcType=VARCHAR}, #{item.ruleStatus,jdbcType=TINYINT},
#{item.tableDescList,jdbcType=VARCHAR}, #{item.gmtCreateUser,jdbcType=INTEGER}, now(),
#{item.gmtModifiedUser,jdbcType=INTEGER}, #{item.isDelete,jdbcType=TINYINT},
#{item.remark,jdbcType=VARCHAR})
</foreach>
ON DUPLICATE KEY UPDATE
sql_str = VALUES(sql_str),
rule_status = VALUES(rule_status),
table_desc_list = VALUES(table_desc_list),
gmt_create_user = VALUES(gmt_create_user),
gmt_modified_user = VALUES(gmt_modified_user),
remark = VALUES(remark),
gmt_create = now(),
gmt_modified = now(),
is_delete = 0
</insert>
注意:rule_name、type组成联合唯一索引,所以我在ON DUPLICATE KEY UPDATE后面没有加上这两个字段,因为这两个字段的数据和之前是没有改变的,所以没必要。
上面的代码有几点需要注意一下:
1、ON DUPLICATE KEY UPDATE后面需要批量更新的字段的顺序与INSERT INTO后面的字段顺序无关。
2、ON DUPLICATE KEY UPDATE后面需要更新的字段是可以在INSERT INTO后面不列出,但是在表中存在的字段(如gmt_create)。
3、ON DUPLICATE KEY UPDATE后面的字段取的数据是在执行完INSERT语句后入表的最新数据,而不是之前的旧数据(如VALUES(sql_str),其中sql_str的值取的是入表时最新的数据而不是表中以前的旧数据)。
4、VALUES后面需要更新的字段与表中字段需要完全相同,而与入参实体中的字段没有什么关联性。
5、示例中包含了VARCHAR、INTEGER、DATE、TINYINT等类型的写法(甚至可以直接写具体的值)。