Mybatis中ON DUPLICATE KEY UPDATE与useGeneratedKeys混用陷阱

最近项目中遇到想要在唯一索引字段相同的情况下更新表中数据,并且返回主键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)作为条件再去查询一下。(没啥办法吧?如果有办法请在评论区赐教)

猜你喜欢

转载自blog.csdn.net/qq_19734597/article/details/85050406