最近项目中遇到想要在唯一索引字段相同的情况下更新表中数据,并且返回主键ID的场景,此时我的写法是:
<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
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>
这样的写法会造成一个严重的问题,这种写法不会返回主键,要想批量返回主键正确的写法是:
<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
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>
</insert>
所以我现在既需要他批量返回主键,也需要他能在唯一索引字段相同的情况下更新数据。我的写法是:
<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>
1、先将数据入库,如果唯一索引相同,更新。
2、通过联合唯一索引(ruleName、type)作为条件再去查询一下。(没啥办法吧?如果有办法请在评论区赐教)