MySQL保存或更新 saveOrUpdate
1. 引子
在项目开发过程中,有一些数据在写入时候,若已经存在,则覆盖即可。这样可以防止多次重复写入唯一键冲突报错。下面先给出两个MyBatis配置文件中使用saveOrUpdate的示例
<!-- 单条数据保存 -->
<insert id="saveOrUpdate" parameterType="TestVo">
insert into table_name (
col1,
col2,
col3
)
values (
#{field1},
#{field2},
#{field3}
)
on duplicate key update
col1 = #{field1},
col2 = #{field2},
col3 = #{field3}
</insert>
<!-- 批量保存 -->
<insert id="batchSaveOrUpdate" parameterType="java.util.List">
insert into table_name (
col1,
col2,
col3
)
<foreach collection="list" item="item" index="index" separator=",">
values (
#{item.field1},
#{item.field2},
#{item.field3}
)
</foreach>
on duplicate key update
col1 = VALUES (col1),
col2 = VALUES (col2),
col3 = VALUES (col3)
</insert>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
其实对于单行数据
on duplicate key update也可以和批量数据保存一样使用VALUES表达式(VALUES指向新数据)。
通过上面的例子初识MySQL ON DUPLICATE KEY UPDATE语法,下面继续学习~~
2. ON DUPLICATE KEY UPDATE 语法
MySQL的ON DUPLICATE KEY UPDATE语法是指包含ON DUPLICATE KEY UPDATE子句的INSERT语句,当新增的这条语句在数据库中已经存在(已经存在是指这条数据包含的主键或者唯一键在数据库已经存在),则会更新数据库对应的老数据。
下面两条sql语句就是等效的,其中table表中a是唯一键
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1;
- 1
- 2
- 3
- 4
若在table表中,不仅仅存在a这个唯一键,b也是唯一键的情况下,以下两条语句就是等效的
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1 OR b=2 LIMIT 1;
- 1
- 2
- 3
- 4
上面这条update语句的含义是:从表中取出满足a=1或者b=2的一条数据,进行更新操作。
下面重点了解以下几个问题:
2.1 多个唯一键
对于一张包含多个唯一键(多个唯一键指有多个键,而不是一个键中包含多个字段)的情况下,一定要注意多个唯一键是否会对应多条数据
从上述第二个例子可以看出,ON DUPLICATE KEY UPDATE会根据a=1或b=2匹配出一条数据进行更新,当此时对应多条数据时候,这种更新操作就会有不确定性。(从另一个角度考虑,若多个唯一键都是一一对应,那么更新操作也不会有问题)
2.2 影响行数返回值
数据不存在,新增数据返回1
数据已存在,修改数据返回2
数据已存在,但未变化返回0
数据是否存在根据唯一键判断,数据是否修改根据ON DUPLICATE KEY UPDATE后的语句判断
下面是一个ON DUPLICATE KEY UPDATE返回值各种情况的简单实例:
mysql> CREATE TABLE test1 (a INT PRIMARY KEY AUTO_INCREMENT , b INT, c INT);
Query OK, 0 rows affected (0.01 sec)
mysql> INSERT INTO test1(a, b ,c) VALUES (1, 1, 1);
Query OK, 1 row affected (0.00 sec)
mysql> select * from test1;
+---+------+------+
| a | b | c |
+---+------+------+
| 1 | 1 | 1 |
+---+------+------+
1 row in set (0.00 sec)
mysql> INSERT INTO test1(a, b ,c) VALUES (1, 1, 1) ON DUPLICATE KEY UPDATE c = c + 1;
Query OK, 2 rows affected (0.00 sec)
mysql> select * from test1;
+---+------+------+
| a | b | c |
+---+------+------+
| 1 | 1 | 2 |
+---+------+------+
1 row in set (0.00 sec)
mysql> INSERT INTO test1(a, b ,c) VALUES (2, 2, 2) ON DUPLICATE KEY UPDATE c = c + 1;
Query OK, 1 row affected (0.00 sec)
mysql> select * from test1;
+---+------+------+
| a | b | c |
+---+------+------+
| 1 | 1 | 2 |
| 2 | 2 | 2 |
+---+------+------+
2 rows in set (0.00 sec)
mysql> INSERT INTO test1(a, b ,c) VALUES (2, 2, 3) ON DUPLICATE KEY UPDATE c = VALUES(c);
Query OK, 2 rows affected (0.00 sec)
mysql> select * from test1;
+---+------+------+
| a | b | c |
+---+------+------+
| 1 | 1 | 2 |
| 2 | 2 | 3 |
+---+------+------+
2 rows in set (0.00 sec)
mysql> INSERT INTO test1(a, b ,c) VALUES (2, 2, 3) ON DUPLICATE KEY UPDATE c = VALUES(c);
Query OK, 0 rows affected (0.00 sec)
mysql> select * from test1;
+---+------+------+
| a | b | c |
+---+------+------+
| 1 | 1 | 2 |
| 2 | 2 | 3 |
+---+------+------+
2 rows in set (0.00 sec)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
注意返回值与新增、修改之间的关系
2.3 新老数据引用
从上面的例子,和触发器做类比,在
ON DUPLICATE KEY UPDATE子句后面,直接使用字段名,引用的是老数据;使用VALUES,引用的是要插入更新的新数据。(例如:c=c+1是在老数据的c字段上加1,c=VALUES(c)是拿新数据覆盖老数据)
2.4 批量保存
批量保存使用ON DUPLICATE KEY UPDATE的场景,请回过头参照文章开始的示例中的第二个用法。
参考自官网:http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html
MySQL保存或更新 saveOrUpdate的更多相关文章
- Hibernate入门(八)级联保存或更新(含问题在末尾,求大佬指点..)
级联保存或更新CASCADE 级联保存或更新: 作用就是:保存一方的数据的时候,会把关联的对象也同时保存. 级联保存或更新的配置: 属性名:cascade 属性值: 1.none:所有情况下均不进行关 ...
- SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量
SparkStreaming直连方式读取kafka数据,使用MySQL保存偏移量 1. ScalikeJDBC 2.配置文件 3.导入依赖的jar包 4.源码测试 通过MySQL保存kafka的偏移量 ...
- Mysql跨表更新 多表update sql语句总结
Mysql跨表更新一直是大家所关心的话题,本文介绍mysql多表 update在实践中几种不同的写法 假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Price:另外一张表是P ...
- mysql保存中文乱码的原因和解决办法
当你遇到这个mysql保存中文乱码问题的时候,期待找到mysql保存中文乱码的原因和解决办法这样一篇能解决问题的文章是多么激动人心. 也许30%的程序员会选择自己百度,结果发现网友已经贴了很多类 ...
- 基于Html5 Plus + Vue + Mui 移动App开发(三)-文件操作(读取、保存、更新数据)
随着手机的发展,现在越来越多的人选择在手机上看书.无论是专业书籍.文学.英语还是网络小说,在手机上看新闻成了人们处理零碎时间的办法.在智能手机里安装一个资讯APP,可以随时.随地查看自己想看的资讯 ...
- PHP利用MySQL保存session
实现环境: PHP 5.4.24 MySQL 5.6.19 OS X 10.9.4/Apache 2.2.26 一.代码 CREATE TABLE `session` ( `skey` ) CHARA ...
- Mysql跨表更新
Mysql跨表更新一直是大家所关心的话题,本文介绍mysql多表 update在实践中几种不同的写法,需要的朋友可以参考下 假定我们有两张表,一张表为Product表存放产品信息,其中有产品价格列Pr ...
- PHP利用MySQL保存session(php5.4之前的处理)
简介 使用MySQL保存session,需要保存三个关键性的数据:session id.session数据.session生命期. 考虑到session的使用方式,没必要使用InnoDB引擎,MyIS ...
- mysql 保存23:59:59 自动加一秒
mysql保存系统传递的时间会诡异的增加一秒钟使用如下工具类: public static Date getEndOfDay(Date date) { Calendar calendarEnd = C ...
随机推荐
- 个人作业Week2-代码复审
代码复审Check List 概要部分 代码能符合需求和规格说明么? 符合.针对-c和-s可以将正确的结果输出到相应的sudoku.txt,并在规定的时间内求解. 代码设计是否有周全的考虑? 有的.我 ...
- final发布简评
1.nice!——约跑app:本次发布使用摄像头展示,比之前清晰的多,展示效果很好,值得学习!功能都已实现,已经可以使用,好评. 2.飞天小女警——礼物挑选:本次发布风格与上次不同,除此之外添加了猜你 ...
- CI框架 default_controller 如何设置为:'目录/Controller' 转
闲谈 前几天,我的室友发现了一个问题:CI框架的Router.php文件的default_controller设置为application\controllers文件下的 一级PHP文件名 就可以,设 ...
- php多进程pcntl学习(一)
pcntl在windows下无法使用,linux编译php时加上参数--enable-pcntl 即可.第一次使用pcntl模块,遇到了一些坑也慢慢填上了,这里简单记录下. 1. 子进程之间变量无法共 ...
- Python day7之mysql
写在前面: 由于毕业论文撰写和答辩耽搁了几个月,但是在这几个月没有放弃学习Python,就是没有时间写博客.进行我们主要对数据库mysql的操作指令集的学习. 一.mysql术语 Mysql是最流行的 ...
- HDU 4280 Island Transport(网络流,最大流)
HDU 4280 Island Transport(网络流,最大流) Description In the vast waters far far away, there are many islan ...
- 洛谷P2605 基站选址
神TM毒瘤线段树优化DP......新姿势get. 题意:有n个村庄,在里面选不多于k个建立基站. 建立基站要ci的费用.如果一个村庄方圆si内没有基站,那么又要支出wi的费用.求最小费用. 解:很显 ...
- Json对象与Json字符串
- 借读:分布式锁和双写Redis
本帖最后由 howtodown 于 2016-10-3 16:01 编辑问题导读1.为什么会产生分布式锁?2.使用分布式锁的方法有哪些?3.本文创造的分布式锁的双写Redis框架都包含哪些内容? ...
- log4j2打印jdbcTemplate的sql以及参数
log4j2打印jdbcTemplate的sql以及参数 ——IT唐伯虎 摘要: log4j2打印jdbcTemplate的sql以及参数. 在log4j2.xml加上这两个logger即可: < ...