Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践
转:
Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践
一、前言
在日常业务开发中经常有这样一个场景,首先创建一条记录,然后插入到数据库;如果数据库已经存在同一主键的记录,则执行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:

四、参考
https://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
Mysql中INSERT ... ON DUPLICATE KEY UPDATE的实践的更多相关文章
- MySQL的INSERT ··· ON DUPLICATE KEY UPDATE使用的几种情况
在MySQL数据库中,如果在insert语句后面带上ON DUPLICATE KEY UPDATE 子句,而要插入的行与表中现有记录的惟一索引或主键中产生重复值,那么就会发生旧行的更新:如果插入的行数 ...
- SQLSERVER 中实现类似Mysql的 INSERT ON DUPLICATE KEY UPDATE
通过SQLServer创建索引时,有一个IGNORE_DUP_KEY的选项,可以类似实现. IGNORE_DUP_KEY = { ON | OFF } 指定对唯一聚集索引或唯一非聚集索引执行多行插入操 ...
- mysql 插入重复值 INSERT ... ON DUPLICATE KEY UPDATE
向数据库插入记录时,有时会有这种需求,当符合某种条件的数据存在时,去修改它,不存在时,则新增,也就是saveOrUpdate操作.这种控制可以放在业务层,也可以放在数据库层,大多数数据库都支持这种需求 ...
- mysql INSERT ... ON DUPLICATE KEY UPDATE语句
网上关于INSERT ... ON DUPLICATE KEY UPDATE大多数文章都是同一篇文章转来转去,首先这个语法的目的是为了解决重复性,当数据库中存在某个记录时,执行这条语句会更新它,而不存 ...
- INSERT ... ON DUPLICATE KEY UPDATE Syntax
一 mybatis中返回自动生成的id 当有时我们插入一条数据时,由于id很可能是自动生成的,如果我们想要返回这条刚插入的id怎么办呢.在mysql数据中我们可以在insert下添加一个selectK ...
- 死锁问题------------------------INSERT ... ON DUPLICATE KEY UPDATE*(转)
前言 我们在实际业务场景中,经常会有一个这样的需求,插入某条记录,如果已经存在了则更新它如果更新日期或者某些列上的累加操作等,我们肯定会想到使用INSERT ... ON DUPLICATE K ...
- INSERT ... ON DUPLICATE KEY UPDATE产生death lock死锁原理
前言 编辑 我们在实际业务场景中,经常会有一个这样的需求,插入某条记录,如果已经存在了则更新它如果更新日期或者某些列上的累加操作等,我们肯定会想到使用INSERT ... ON DUPLICATE K ...
- INSERT ... ON DUPLICATE KEY UPDATE Syntax 专题
ON DUPLICATE KEY UPDATE :不用用于批量,除 insert into t1 select * from t2 on duplicated key update k1=v1,k2 ...
- 可遇不可求的Question之INSERT … ON DUPLICATE KEY UPDATE 语法篇
MySQL 自4.1版以后开始支持INSERT … ON DUPLICATE KEY UPDATE语法,使得原本需要执行3条SQL语句(SELECT,INSERT,UPDATE),缩减为1条语句即可完 ...
随机推荐
- Django--ORM和单表查询
一 . ORM ORM是“对象-关系-映射”的简称.(Object Relational Mapping,简称ORM) 二. 单表操作 要想将模型转为mysql数据库中的表,需要在setting里面写 ...
- 阿里云ECS服务器,CentOS 7.4配置jdk+tomcat+mysql
参考博客: https://mp.weixin.qq.com/s?__biz=MzIxMzk3Mjg5MQ==&mid=2247484020&idx=1&sn=6e0aa07f ...
- Delphi调用MSSQL存储过程返回的多个数据集的方法
varaintf:_Recordset;RecordsAffected:OleVariant; begin ADOStoredProc1.Close;ADOStoredProc1.Open;aintf ...
- 解决Safari页面缓存的问题
在开发一个移动应用的过程中,遇到问题:在订单确认页,用户点击 收货地址链接,跳转到地址选择页面,咋选一个地址,跳转回订单确认页,发现收货地址没有改变,还是最开始的地址. 用Android手机发现地址有 ...
- onbeforeunload事件两种写法及效果
在符合W3C标准的浏览器里,可以使用addEventListener方法来添加事件. 当不需要为一个事件添加多个处理函数的时候,可以简单的使用onXXX=function(){}的方式来添加事件处理函 ...
- cefSharp 开发随笔
最近用cefSharp开发一点简单的东西.记录一点随笔,不定时更新. 1.用nuget安装完之后,架构要选择x86或者x64,否则编译会报错(截止到Chrome 55版本) 2.向Chrome注册C# ...
- 线程同步Volatile与Synchronized(一)
volatile 一.volatile修饰的变量具有内存可见性 volatile是变量修饰符,其修饰的变量具有内存可见性. 可见性也就是说一旦某个线程修改了该被volatile修饰的变量,它会保证修改 ...
- Process 模块的方法
join from multiprocessing import Process import time, os def task(name): print('%s is running' % nam ...
- CML\LVDS
LVDS和CML电平应用区别 https://wenku.baidu.com/view/6bb0066f011ca300a6c3908c.html
- Create an Azure SQL database in the Azure portal
Create a SQL database An Azure SQL database is created with a defined set of compute and storage res ...