• Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践


    转:

    Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践

    0.1 2018.03.23 17:19* 字数 492 阅读 2613评论 2

    一、前言

    在日常业务开发中经常有这样一个场景,首先创建一条记录,然后插入到数据库;如果数据库已经存在同一主键的记录,则执行update操作,如果不存在,则执行insert操作;

    这个操作可以在业务层做,也可以在数据库层面做;

    业务层一般做法是先查询,如果不存在在插入,如果存在则更新,但是查询和插入不是原子性操作,在并发量比较高的时候,可能两个线程都查询某个记录不存在,所以会执行两次插入,然后其中一条必然会因为主键(这里说的主键不是递增主键)冲突而失败。

    数据库层mysql中INSERT ... ON DUPLICATE KEY UPDATE就可以做这个事情,并且是原子性操作,本文就来讲解的使用。

    二、INSERT ... ON DUPLICATE KEY UPDATE命令

    2.1单条记录下使用

    
    INSERT INTO t1 (a,b,c) VALUES (1,2,3)
      ON DUPLICATE KEY UPDATE c=c+1;
    

    如上sql假如t1表的主键或者UNIQUE 索引是a,那么当执行上面sql时候,如果数据库里面已经存在a=1的记录则更新这条记录的c字段的值为原来值+1,然后返回值为2。如果不存在则插入a=1,b=2,c=3到数据库,然后返回值为1。

    2.2多记录下使用

    INSERT INTO t1 (a,b,c) VALUES (1,2,3),(4,5,6)
      ON DUPLICATE KEY UPDATE c=VALUES(c);
    

    三、MyBatis下使用

    Mybatis作为经典的数据库持久层框架,自然要介绍下它下的使用

    • 在mapper.xml里面配置如下:
      假设a为主键
    <insert id="insertOrUpdate">
            INSERT INTO t1 (a,b,c) 
            values
            <foreach collection="list" item="item"  separator=",">
                (#{item.a},#{item.b},#{item.c})
            </foreach>
            ON DUPLICATE KEY UPDATE c=values(c),b=values(b)
     </insert>
    
    • 对应的mapper接口可以定义为:
    long insertOrUpdate(List<Test> list);
    
    class Test{
    private int a;
    private int b;
    private int c;
    ...
    }
    

    注:mysql中sql字符串大小有限制,我本机的mysql上执行show VARIABLES like '%max_allowed_packet%';结果为max_allowed_packet为4M:

    image.png

    四、参考

    https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html

  • 相关阅读:
    k8s笔记0528-基于KUBERNETES构建企业容器云手动部署集群记录-4
    k8s笔记0528-基于KUBERNETES构建企业容器云手动部署集群记录-2
    Mysql索引最佳实践笔记0524
    Mysql 5.6 编译报错
    MySQL 源码安装规范
    CentOS 7.3安装Zabbix3.2
    Mysql for Mac 安装及环境配置
    win10下Resin安装--入门(1)
    React---入门(1)
    SVN简介与安装
  • 原文地址:https://www.cnblogs.com/libin6505/p/10756213.html
Copyright © 2020-2023  润新知