mysql中insert并發(fā)問題(on?DUPLICATE?KEY?UPDATE)
小編最近在項目中,遇到了一個問題,因為并發(fā)insert造成了臟數(shù)據(jù),主要場景是:
- 根據(jù)查詢數(shù)據(jù)庫的結(jié)果:存在,則進(jìn)行更新;不存在,則進(jìn)行新增;
- 還有一個場景需求:若已存在,則僅查詢;不存在,則進(jìn)行新增;
百度發(fā)現(xiàn),mysql已經(jīng)為我們提供了相應(yīng)的sql語句去實現(xiàn)這些場景。
一、insert,存在則更新,不存在則新增
語法:on DUPLICATE KEY UPDATE
1、表結(jié)構(gòu)如下:
CREATE TABLE `testMfc` ( `id` int(11) NOT NULL AUTO_INCREMENT, `age` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL, `num` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uk_01` (`age`,`name`) ) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4
注意:想要使用該語法,必須利用“唯一索引”或者“主鍵索引”,只有產(chǎn)生“索引沖突”,該語法才能正常生效。
此處建立唯一索引:age列和name列
插入初始數(shù)據(jù):
insert into testMfc values (null, 1,'1',30),(null,2,'2',40)
2、sql語句
已存在,則更新:(影響行數(shù)為:2,如果使用mybatis,返回值 int =2,同時該語句可返回當(dāng)前 主鍵)
insert into testMfc values (null, 1,'1',30) on duplicate key update num = 1;
不存在,則新增:(影響行數(shù)為:1,如果使用mybatis,返回值 int =1,同時該語句可返回當(dāng)前 主鍵)
insert into testMfc values (null, 3,'3',50) on duplicate key update num = 1;
3、批量插入,某一條記錄存在,則更新;其余進(jìn)行新增
insert into testMfc values (null, 3,'3',300), (null, 4,'4',400), (null, 5,'5',500), (null, 2,'2',200) on duplicate key update num = values(num);
更新:age = 2 和 age =3 的num屬性,新增age = 4 和 5 的數(shù)據(jù)
注意: num = values(num) ,此處的格式,必須是 values(列名),才能更新到對應(yīng)的行。
mybatis語法:(與該表無關(guān),則用作語法參考)
@Insert({ "<script>", "insert into weekly_item (weekly_id, weekly_task_name," + "task_id, plan, project_id,duty_user_key, status, copy_status," + "create_at, update_at, comment_id,complete)" + "<foreach collection='insertList' item='item' open='values ' separator=','> " + "(#{item.weeklyId,jdbcType=INTEGER}," + "#{item.weeklyTaskName,jdbcType=VARCHAR}," + "#{item.taskId,jdbcType=INTEGER}," + "#{item.plan,jdbcType=VARCHAR}," + "#{item.projectId,jdbcType=INTEGER}," + "#{item.dutyUserKey,jdbcType=VARCHAR}," + "#{item.status,jdbcType=TINYINT}," + "#{item.copyStatus,jdbcType=TINYINT}," + "now()," + "now()," + "#{item.commentId,jdbcType=INTEGER}," + "#{item.complete,jdbcType=VARCHAR})" + "</foreach>"+ "ON DUPLICATE KEY UPDATE " + "complete = VALUES(complete)", "</script>" }) void insertBatchOrUpdate(@Param("insertList") List<WeeklyItem> copyItemList);
二、insert,存在則不進(jìn)行任何操作;不存在則新增
語法:insert ignore into 表名
1、sql語句
注意:
- 已存在:(影響行數(shù)為:0,如果使用mybatis,返回值 int =0,該語句不能 返回當(dāng)前 主鍵)
- 不存在則新增:(影響行數(shù)為:1,如果使用mybatis,返回值 int =1,該語句 可以 返回當(dāng)前 主鍵)
insert ignore into testMfc values (null,1,'1',123);
三、總結(jié)
mysql還提供了其他原子性操作,比如說:insert,若已存在,則先刪除再新增,個人覺得可以使用存在則更新操作代替,所以此處就不做介紹,希望對你們有用。
備注: 網(wǎng)上有人提問,on DUPLICATE KEY UPDATE 在mysql客戶端可以正常使用,但是在mybatis就沒有效果,既不更新也不新增,同時語句還不報錯。小編剛也遇到了“類似情況”,后來發(fā)現(xiàn)是參數(shù)傳錯了,粗心了呀。還有一個是sql語句insert的時候,將id也賦值了,這個時候就是主鍵沖突了??赡懿皇俏覀兿胍淖远x“唯一索引”
到此這篇關(guān)于mysql中insert并發(fā)問題(on DUPLICATE KEY UPDATE)的文章就介紹到這了,更多相關(guān)mysql insert并發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
windows下安裝、卸載mysql服務(wù)的方法(mysql 5.6 zip解壓版安裝教程)
這篇文章主要介紹了windows下安裝、卸載mysql服務(wù)的方法(zip解壓版安裝),需要的朋友可以參考下2016-06-06MySql5.6使用validate password 插件加強(qiáng)密碼強(qiáng)度的安裝及使用方法
在mysql5.6中使用validate password插件加強(qiáng)密碼強(qiáng)度,支持密碼的強(qiáng)度要求,是一款非常好用的密碼加強(qiáng)插件,下面小編通過本文給大家介紹MySql5.6使用validate password 插件加強(qiáng)密碼強(qiáng)度的安裝及使用方法,小伙伴們一起學(xué)習(xí)吧2016-07-07