1. 引子

在项目开发过程中,有一些数据在写入时候,若已经存在,则覆盖即可。这样可以防止多次重复写入唯一键冲突报错。下面先给出两个MyBatis配置文件中使用saveOrUpdate的示例

<!-- 单条数据保存 -->
<insert id="saveOrUpdate" parameterType="TestVo">insert into table_name (col1,col2,col3)values (#{field1},#{field2},#{field3})on duplicate key updatecol1 = #{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 updatecol1 = VALUES (col1),col2 = VALUES (col2),col3 = VALUES (col3)
</insert>

其实对于单行数据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;

若在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;

上面这条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)

注意返回值与新增、修改之间的关系

2.3 新老数据引用

从上面的例子,和触发器做类比,在ON DUPLICATE KEY UPDATE子句后面,直接使用字段名,引用的是老数据;使用VALUES,引用的是要插入更新的新数据。(例如: c=c+1是在老数据的c字段上加1,c=VALUES©是拿新数据覆盖老数据)

2.4 批量保存

批量保存使用ON DUPLICATE KEY UPDATE的场景,请回过头参照文章开始的示例中的第二个用法。

参考自官网:http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html

MySQL保存或更新 saveOrUpdate相关推荐

  1. 使用MySql保存session

    2019独角兽企业重金招聘Python工程师标准>>> 本文来源于:http://www.lai18.com/content/433951.html 本文实例讲述了php使用MySQ ...

  2. 用 PHP 和 MySQL 保存和输出图片

    用 PHP 和 MySQL 保存和输出图片 在我们设计和制作网站的过程中,有时把图片保存到数据库中要比存成文件的形式更加方便.和MySQL这对黄金组合可以很容易的实现上述功能.在本文中,我们将会向读者 ...

  3. mysql保存中文乱码的原因和解决办法

    当你遇到这个mysql保存中文乱码问题的时候,期待找到mysql保存中文乱码的原因和解决办法这样一篇能解决问题的文章是多么激动人心.   也许30%的程序员会选择自己百度,结果发现网友已经贴了很多类似 ...

  4. mysql解决丢失更新_mysql 数据丢失更新的解决方法

    最新看<innodb 引擎内幕>,作者有介绍丢失更新的问题,这里记录自己的想法和方案 --------------------------------------------------- ...

  5. MySQL 插入、更新、删除、简单检索

    MySQL 插入.更新.删除.简单检索 创建环境: CREATE TABLE `test_user` (`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户 ...

  6. MySQL添加、更新、删除数据

    MySQL添加.更新.删除数据 1.查询数据 select * from student; 2.添加数据 insert into student values(1,"张三",&qu ...

  7. mysql保存时乱码了_MySQL保存中文乱码的原因和解决办法

    (3)MySQL的字符集设置. 这个是重点了,一般都是在这里搞错而出现了mysql乱码. mysql编码设置可以分为三种设置:数据库的编码.表的编码.和字段的编码. a.数据库的编码: 在sqlyog ...

  8. mysql删除新添加数据,MySQL添加、更新与删除数据

    添加.更新与删除数据 添加数据 为表中所有字段添加数据 INSERT INTO 表名(字段名1,字段名2,--) VALUES(值1,值2,--); insert into 表名 values(值1, ...

  9. mysql保存23:59:59时,自动加一秒

    今天遇到一个问题,发现mysql保存2018-08-22  23:59:59的时间时会自动加一秒,存到库中就变成了2018-08-23 00:00:00,经查阅资料发现是因为MySQL数据库对于毫秒大 ...

最新文章

  1. linux find命令通配,Linux Find 命令的详解与研究
  2. PowerDesigner 常用设置
  3. Java 8 - 收集器Collectors
  4. 收藏 | 700页NLP算法在百度、阿里、腾讯等一线大厂的最佳实践!PDF限时领!
  5. 静态库与动态库(一):概述
  6. nginx.conf配置格式
  7. SAP全球技术研发者大会上海站电子票欣赏
  8. 由浅入深逐步了解 Synchronized
  9. 面向对象之软件需求中的体系构造
  10. Android Error:warning: Ignoring InnerClasses attribute for an anonymous inner class
  11. dhtml、html、html5、xml、xhtml的区别
  12. debian中网易云音乐打不开的一种解决方法
  13. 线上软文自媒体推广怎么做,软文推广有什么好处?
  14. Appium移动自动化测试(三)--安装Android模拟器(建议直接连手机,跳过此步)
  15. 第13章 项目合同管理
  16. 突破!Matlab国产替代品Truffer官宣取得实质进步
  17. 计算机二级考试电子表真题,全国计算机等级考试电子表格题目
  18. 电脑书籍下载【申明:来源于网络】
  19. Python爬虫获取东财沪深A股当天收盘后的详细数据(量化投资一)
  20. 科学计算机怎么算斜长,斜长简易计算公式

热门文章

  1. 联想m7400pro清零方法_联想打印机怎么清零 联想打印机清零方法【教程】
  2. 探测器反向偏压_近红外和可见光双模有机光电探测器
  3. python中导入模块队列_【每日学习】Python中模块的导入
  4. 有重复数字的组合问题_带数字重复的组合和问题
  5. Spring Boot 最佳实践(五)Spring Data JPA 操作 MySQL 8
  6. WinXP下变量方式表达对应路径说明
  7. 2s相机 android6,Android Camera2 使用总结
  8. 决定c++语言中函数的返回值类型的是,全国2009年10月高等教育自学考试C++程序设计试题及部分参考答案...
  9. matlab彩色图像缩放(双线性与双立方插值)
  10. springboot python 开发效率比较-2018年Java开发值得学习的10大技术