MySQL保存或更新 saveOrUpdate
1. 引子
在項目開發(fā)過程中,有一些數(shù)據(jù)在寫入時候,若已經(jīng)存在,則覆蓋即可。這樣可以防止多次重復寫入唯一鍵沖突報錯。下面先給出兩個MyBatis配置文件中使用saveOrUpdate的示例
<!-- 單條數(shù)據(jù)保存 --> <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>其實對于單行數(shù)據(jù)on duplicate key update也可以和批量數(shù)據(jù)保存一樣使用VALUES表達式(VALUES指向新數(shù)據(jù))。
通過上面的例子初識MySQL ON DUPLICATE KEY UPDATE語法,下面繼續(xù)學習~~
2. ON DUPLICATE KEY UPDATE 語法
MySQL的ON DUPLICATE KEY UPDATE語法是指包含ON DUPLICATE KEY UPDATE子句的INSERT語句,當新增的這條語句在數(shù)據(jù)庫中已經(jīng)存在(已經(jīng)存在是指這條數(shù)據(jù)包含的主鍵或者唯一鍵在數(shù)據(jù)庫已經(jīng)存在),則會更新數(shù)據(jù)庫對應的老數(shù)據(jù)。
下面兩條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的一條數(shù)據(jù),進行更新操作。
下面重點了解以下幾個問題:
2.1 多個唯一鍵
對于一張包含多個唯一鍵(多個唯一鍵指有多個鍵,而不是一個鍵中包含多個字段)的情況下,一定要注意多個唯一鍵是否會對應多條數(shù)據(jù)
從上述第二個例子可以看出,ON DUPLICATE KEY UPDATE會根據(jù)a=1或b=2匹配出一條數(shù)據(jù)進行更新,當此時對應多條數(shù)據(jù)時候,這種更新操作就會有不確定性。(從另一個角度考慮,若多個唯一鍵都是一一對應,那么更新操作也不會有問題)
2.2 影響行數(shù)返回值
數(shù)據(jù)不存在,新增數(shù)據(jù)返回1
數(shù)據(jù)已存在,修改數(shù)據(jù)返回2
數(shù)據(jù)已存在,但未變化返回0
數(shù)據(jù)是否存在根據(jù)唯一鍵判斷,數(shù)據(jù)是否修改根據(jù)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 新老數(shù)據(jù)引用
從上面的例子,和觸發(fā)器做類比,在ON DUPLICATE KEY UPDATE子句后面,直接使用字段名,引用的是老數(shù)據(jù);使用VALUES,引用的是要插入更新的新數(shù)據(jù)。(例如: c=c+1是在老數(shù)據(jù)的c字段上加1,c=VALUES?是拿新數(shù)據(jù)覆蓋老數(shù)據(jù))
2.4 批量保存
批量保存使用ON DUPLICATE KEY UPDATE的場景,請回過頭參照文章開始的示例中的第二個用法。
參考自官網(wǎng):http://dev.mysql.com/doc/refman/5.5/en/insert-on-duplicate.html
總結
以上是生活随笔為你收集整理的MySQL保存或更新 saveOrUpdate的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【NLP】文本分类还停留在BERT?对偶
- 下一篇: 研究生调剂!!急!!!跪求解答!!?