詳解mysql插入數(shù)據(jù)后返回自增ID的七種方法
mysql 和 oracle 插入的時候有一個很大的區(qū)別是:
oracle 支持序列做 id; mysql 本身有一個列可以做自增長字段。mysql 在插入一條數(shù)據(jù)后,如何能獲得到這個自增 id 的值呢?
一:使用 last_insert_id()SELECT LAST_INSERT_ID();
1. 每次 mysql 的 query 操作在 mysql 服務器上可以理解為一次“原子”操作, 寫操作常常需要鎖表, 這里的鎖表是 mysql 應用服務器鎖表不是我們的應用程序鎖表。
2. 因為 LAST_INSERT_ID 是基于 Connection 的,只要每個線程都使用獨立的 Connection 對象,LAST_INSERT_ID 函數(shù) 將返回該 Connection 對 AUTO_INCREMENT列 最新的 insert or update* 作生成的第一個 record 的ID。這個值不能被其它客戶端(Connection)影響,保證了你能夠找回自己的 ID 而不用擔心其它客戶端的活動,而且不需要加鎖。使用單INSERT 語句插入多條記錄, LAST_INSERT_ID 返回一個列表。 3. LAST_INSERT_ID 是與 table 無關的,如果向表 a 插入數(shù)據(jù)后,再向表 b 插入數(shù)據(jù),LAST_INSERT_ID 會改變。
二:使用 max(id)如果不是頻繁的插入我們也可以使用這種方法來獲取返回的id值
select max(id) from user;
這個方法的缺點是不適合高并發(fā)。如果同時插入的時候返回的值可能不準確。
三:創(chuàng)建一個存儲過程在存儲過程中調用先插入再獲取最大值的操作。
DELIMITER $$DROP PROCEDURE IF EXISTS `test` $$CREATE DEFINER=`root`@`localhost` PROCEDURE `test`(in name varchar(100),out oid int)BEGIN insert into user(loginname) values(name); select max(id) from user into oid; select oid;END $$DELIMITER ;call test(’gg’,@id);四:使用 @@identity
select @@IDENTITY
@@identity 是表示的是最近一次向具有 identity 屬性(即自增列)的表插入數(shù)據(jù)時對應的自增列的值,是系統(tǒng)定 義的全局變量。一般系統(tǒng)定義的全局變量都是以@@開頭,用戶自定義變量以@開頭。比如有個表 A,它的自增列是 id,當向 A 表插入一行數(shù)據(jù)后,如果插入數(shù)據(jù) 后自增列的值自動增加至 101,則通過select @@identity得到的值就是 101。使用@@identity的前提是在進行 insert 操作后,執(zhí)行 select @@identity 的時候連接沒有關閉,否則得到的將是 NULL 值。
五:是使用 getGeneratedKeys()Connection conn = ;Serializable ret = null;PreparedStatement state = .;ResultSet rs=null;try { state.executeUpdate(); rs = state.getGeneratedKeys(); if (rs.next()) { ret = (Serializable) rs.getObject(1); } } catch (SQLException e) {}return ret;
總結:在 mysql 中做完插入之后獲取 id 在高并發(fā)的時候是很容易出錯的。另外 last_insert_id 雖然是基于 session 的但是不知道為什么沒有測試成功。
六:selectkey:其實在 ibtias 框架里使用 selectkey 這個節(jié)點,并設置 insert 返回值的類型為 integer,就可以返回這個 id 值。
SelectKey 在Mybatis中是為了解決 Insert 數(shù)據(jù)時不支持主鍵自動生成的問題,他可以很隨意的設置生成主鍵的方式。
不管 SelectKey 有多好,盡量不要遇到這種情況吧,畢竟很麻煩。
SelectKey 需要注意 order 屬性:
Mysql 一類支持自動增長類型的數(shù)據(jù)庫中,order 需要設置為 after 才會取到正確的值。 Oracle 這樣取序列的情況,需要設置為 before,否則會報錯。xml 的例子:
<insert parameterType='map'> insert into table1 (name) values (#{name}) <selectKey resultType='java.lang.Integer' keyProperty='id'> SELECT LAST_INSERT_ID() AS id </selectKey> </insert>
上面 xml 的傳入?yún)?shù)是 map,selectKey 會將結果放到入?yún)?shù) map 中。用 POJO 的情況一樣,但是有一點需要注意的是,keyProperty 對應的字段在 POJO 中必須有相應的 setter 方法,setter 的參數(shù)類型還要一致,否則會報錯。
注解的形式:
@Insert('insert into table2 (name) values(#{name})') @SelectKey(statement='call identity()', keyProperty='nameId', before=false, resultType=int.class) int insertTable2(Name name); 方法七:使用<insert 中的useGeneratedKeys 和 keyProperty 兩個屬性
1.在Mybatis Mapper文件中添加屬性 “useGeneratedKeys”和“keyProperty”,其中 keyProperty 是 Java 對象的屬性名,而不是表格的字段名。
<insert parameterType='Spares' useGeneratedKeys='true' keyProperty='id'> insert into system(name) values(#{name}) </insert>
2.Mybatis 執(zhí)行完插入語句后,自動將自增長值賦值給對象 systemBean 的屬性id。因此,可通過 systemBean 對應的 getter 方法獲取!
int count = systemService.insert(systemBean); int id = systemBean.getId(); //獲取到的即為新插入記錄的ID
【注意事項】
1.Mybatis Mapper 文件中,“useGeneratedKeys” 和 “keyProperty” 必須添加,而且 keyProperty 一定得和 java 對象的屬性名稱一直,而不是表格的字段名。
2. java Dao中的 Insert 方法,傳遞的參數(shù)必須為 java 對象,也就是 Bean,而不能是某個參數(shù)。
到此這篇關于詳解mysql插入數(shù)據(jù)后返回自增ID的七種方法的文章就介紹到這了,更多相關mysql插入返回自增ID內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持好吧啦網(wǎng)!
相關文章:
1. docker中修改mysql最大連接數(shù)及配置文件的實現(xiàn)2. MyBatis中$和#的深入講解3. MyBatis下SQL注入攻擊的3種方式4. Windows10環(huán)境安裝sdk8的圖文教程5. Fluent Mybatis實現(xiàn)環(huán)境隔離和租戶隔離6. SQLite教程(二):C/C++接口簡介7. SQL-Server2005mssqlserver服務與sqlexpress服務有什么區(qū)別8. SQL Server數(shù)據(jù)倉庫的構建與分析9. SQL Server數(shù)據(jù)庫超級管理員賬號防護知識10. MySQL 性能、監(jiān)控與災難恢復
