- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
在项目开发过程中,有一些数据在写入时候,若已经存在,则覆盖即可。这样可以防止多次重复写入唯一键冲突报错。下面先给出两个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>
其实对于单行数据on duplicate key update也可以和批量数据保存一样使用VALUES表达式(VALUES指向新数据)。
通过上面的例子初识MySQL 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的一条数据,进行更新操作。
对于一张包含多个唯一键(多个唯一键指有多个键,而不是一个键中包含多个字段)的情况下,一定要注意多个唯一键是否会对应多条数据
从上述第二个例子可以看出,ON DUPLICATE KEY UPDATE会根据a=1或b=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)
注意返回值与新增、修改之间的关系
从上面的例子,和触发器做类比,在ON DUPLICATE KEY UPDATE子句后面,直接使用字段名,引用的是老数据;使用VALUES,引用的是要插入更新的新数据。(例如: c=c+1是在老数据的c字段上加1,c=VALUES©是拿新数据覆盖老数据)
批量保存使用ON DUPLICATE KEY UPDATE的场景,请回过头参照文章开始的示例中的第二个用法。
参考自官网:http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html
1. 引子 在项目开发过程中,有一些数据在写入时候,若已经存在,则覆盖即可。这样可以防止多次重复写入唯一键冲突报错。下面先给出两个MyBatis配置文件中使用saveOrUpdate的示例 ins
我有一个名为客户的 hibernate 实体,其中包含有关客户的信息。在我的方法中,我将客户详细信息作为参数获取,我需要将其插入数据库。因此,要删除重复条目,我会检查该客户是否已存在于数据库中。但问题
我尝试在 hibernate 中使用 saveorupdate 方法,结果是 com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViola
我正在尝试做这样的方法,错误出现了并发问题..似乎我的更新方法没有增加我实体的@Version属性。 我的代码是这样的: @Transactional public B sav
saveOrUpdate() does the following: •if the object is already persistent in this session, do nothing
我尝试使用以下代码插入或更新数据库记录: Category category = new Category(); category.setName('catName'); category.setId
我正在通过以下链接使用 struts2 和 hibernate 集成 http://www.tutorials4u.net/struts2-tutorial/struts2_crud_example.
我正在尝试使用 Hibernate 插入或更新大数据。我有一个包含 350k 个对象的列表,当我使用 Hibernate saveOrUpdate() 时,需要几个小时才能插入所有数据。 我使用下面的
当使用 saveOrUpdate 创建一个新的 ebject 时,hibernate 将对象存储在数据库中并正确返回它。但是在同一方法调用中会创建一个带有一些空列的附加对象。 数据库中的对象如下所示:
@SuppressWarnings("unchecked") //@Override public SerialNumber getCounter(String id) { Session c
我的表有 2 个字段 id - 唯一、NotNull 和 Seq 名称 - Varchar 在空表上,我将记录发送为id = 1(手动填写id值) 名称 = '样本' 我使用 saveOrUpdate
我有 2 个双向映射的表,如下 @Entity @Table(name="testplan") public class TestPlan { @Id @Column(name="te
虽然我已经能够找到有关 Hibernate 事务如何工作的信息,因此数据库不会损坏,但更难理解 Hibernate 如何处理在线程之间共享的对象,并且每个线程都尝试将其保存到数据库。 这是我的理论问题
我有一个 Journal 类,它有一个 JournalLine 对象的 IList。 我创建了一个 Journal 并意外地通过相同的行生成方法运行了两次。此方法的开头调用 _journalLines
我正在尝试使用 Hibernate 中的 session.saveOrUpdate() 方法更新表格行。 但是,它无法更新该行并尝试通过生成插入语句来保存它。由于我的数据库中有一些不可为 null 的
我有一个名为 IssueParticipant 的 Hibernate 实体。它基本上描述了用户和问题(类似于 JIRA 或 Bugzilla 问题)之间的关系。它代表数据库中的一种多对多链接表,将用
我创建了一个名为“gauge_category”的表,它只有一个字段“gauge_category_id”是主键,数据类型是可变字符。我尝试了 CRUD 操作。创建、读取、删除操作完美运行。当我更新时
我正在使用 mysql 和 hibernate 在表中插入和更新行。我使用 saveOrUpdate 调用。现在,当我尝试更新表中的一行时,出现异常。异常指出我的列 requestTime 不能为空。
我正在使用 spring 来维护我应用程序中的事务。我想在数据库中保存新的并更新现有的用户详细信息。但是我无法更新对数据库的更改。查看我下面的代码并告诉我我的代码做错了什么? Session ses
我正在尝试使用父对象上的 saveOrUpdate 函数从 Hibernate Java 对象的集合中删除一个项目。更新和插入工作正常,但对象未正确删除。 saveOrUpdate() 是否能够识别和
我是一名优秀的程序员,十分优秀!