聊聊常用的msyql存在即更新的两种方式

102 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

我们使用mysql插入数据,如果数据已经存在怎么办,如果数据违反了主键约束和唯一索引抛出异常,这样用户体验不好;那么,存在即更新就派上用场了。前提是我们的数据表设置了主键或者唯一索引,否则数据只会插入,这样子会导致很多的重复数据。

一、replace into

replace into 跟 insert 功能类似,不同点在于:replace into ⾸先尝试插⼊数据到表中,

  1. 如果发现表中已经有此⾏数据(根据主键或者唯⼀索引判断)则先删除此⾏数据,然后插⼊新的数据。
  2. 否则,直接插⼊新数据。

用例:

<insert id="updateOrInsertUserInfo" useGeneratedKeys="true" keyProperty="id" parameterType="list" >
replace into `corp_user`
    (id, token, user_id,
      name, department, position,
      mobile, email, gender,
      telephone, alias, address
      )
VALUES
<foreach collection="list" item="item" separator=",">
(
        #{item.id,jdbcType=INTEGER}, #{item.token,jdbcType=VARCHAR}, #{item.userId,jdbcType=VARCHAR},
        #{item.name,jdbcType=VARCHAR}, #{item.department,jdbcType=VARCHAR}, #{item.position,jdbcType=VARCHAR},
        #{item.mobile,jdbcType=VARCHAR}, #{item.email,jdbcType=VARCHAR}, #{item.gender,jdbcType=INTEGER},
        #{item.telephone,jdbcType=VARCHAR}, #{item.alias,jdbcType=VARCHAR}, #{item.address,jdbcType=VARCHAR}
)
</foreach>

二、ON DUPLICATE KEY UPDATE

ON DUPLICATE KEY UPDATE 表示存在就执行 update语句,不存在执行 insert语句。

1:ON DUPLICATE KEY UPDATE需要有在INSERT语句中有存在主键或者唯一索引的列, 并且对应的数据已经在表中才会执行更新操作。而且如果要更新的字段是主键或者唯一索引,不能和表中已有的数据重复,否则插入更新都失败。

2:不管是更新还是增加语句都不允许将主键或者唯一索引的对应字段的数据变成表中已经存在的数据。

用例:

    INSERT INTO `corp_user`
    (id, token, user_id,
      name, department, position,
      mobile, email, gender,
      telephone, alias, address)
    VALUES (

        #{id,jdbcType=INTEGER}, #{token,jdbcType=VARCHAR}, #{userId,jdbcType=VARCHAR},
        #{name,jdbcType=VARCHAR}, #{department,jdbcType=VARCHAR}, #{position,jdbcType=VARCHAR},
        #{mobile,jdbcType=VARCHAR}, #{email,jdbcType=VARCHAR}, #{gender,jdbcType=INTEGER},
        #{telephone,jdbcType=VARCHAR}, #{alias,jdbcType=VARCHAR}, #{address,jdbcType=VARCHAR}

    )
    ON DUPLICATE KEY UPDATE
    id=values(id),
    token=values(token),
    user_id=values(user_id),
    name=values(name),
    department=values(department),
    position=values(position),
    mobile=values(mobile),
    email=values(email),
    gender=values(gender),
    telephone=values(telephone),
    alias=values(alias),
    address=values(address)
</insert>

三、参数useGeneratedKeys和keyProperty

useGeneratedKeys=“true”     keyProperty=“id”

useGeneratedKeys设置为 true 时,表示如果插入的表id以自增列为主键,则允许 JDBC 支持自动生成主键,并可将自动生成的主键id返回给调用者。useGeneratedKeys参数只针对 insert 语句生效,默认为 false;

keyProperty取id的key值,对应主键值。

在settings元素中设置useGeneratedKeys是一个全局参数,但是只会对接口映射器产生影响,对xml映射器不起效。

<settings> 
    <!-- 
        允许JDBC支持自动生成主键,需要驱动兼容。 如果设置为true则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。 
    --> 
    <setting name="useGeneratedKeys" value="true" /> 
</settings>