mysql插入數據後返回自增ID的方法

mysql和oracle插入的時候有一個很大的區別是,oracle支持序列作id,mysql自己有一個列能夠作自增加字段,mysql在插入一條數據後,如何能得到到這個自增id的值呢? java

方法一是使用last_insert_id mysql

mysql> SELECT LAST_INSERT_ID();

    產生的ID 每次鏈接後保存在服務器中。這意味着函數向一個給定客戶端返回的值是該客戶端產生對影響AUTO_INCREMENT列的最新語句第一個 AUTO_INCREMENT值的。這個值不能被其它客戶端影響,即便它們產生它們本身的 AUTO_INCREMENT值。這個行爲保證了你可以找回本身的 ID 而不用擔憂其它客戶端的活動,並且不須要加鎖或處理。  sql

    每次mysql_query操做在mysql服務器上能夠理解爲一次「原子」操做, 寫操做經常須要鎖表的, 是mysql應用服務器鎖表不是咱們的應用程序鎖表。 服務器

    值得注意的是,若是你一次插入了多條記錄,這個函數返回的是第一個記錄的ID值。 session

    由於LAST_INSERT_ID是基於Connection的,只要每一個線程都使用獨立的Connection對象,LAST_INSERT_ID函數將返回該Connection對AUTO_INCREMENT列最新的insert or update*做生成的第一個record的ID。這個值不能被其它客戶端(Connection)影響,保證了你可以找回本身的 ID 而不用擔憂其它客戶端的活動,並且不須要加鎖。使用單INSERT語句插入多條記錄,  LAST_INSERT_ID返回一個列表。 併發

    LAST_INSERT_ID 是與table無關的,若是向表a插入數據後,再向表b插入數據,LAST_INSERT_ID會改變。 oracle

方法二是使用max(id) 框架

使用last_insert_id是基礎鏈接的,若是換一個窗口的時候調用則會一直返回10 ide

若是不是頻繁的插入咱們也能夠使用這種方法來獲取返回的id值 函數

select max(id) from user;

這個方法的缺點是不適合高併發。若是同時插入的時候返回的值可能不許確。

方法三是建立一個存儲過程,在存儲過程當中調用先插入再獲取最大值的操做

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屬性(即自增列)的表插入數據時對應的自增列的值,是系統定義的全局變量。通常系統定義的全局變量都是以@@開頭,用戶自定義變量以@開頭。好比有個表A,它的自增列是id,當向A表插入一行數據後,若是插入數據後自增列的值自動增長至101,則經過select @@identity獲得的值就是101。使用@@identity的前提是在進行insert操做後,執行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在高併發的時候是很容易出錯的。另外last_insert_id雖然是基於session的可是不知道爲何沒有測試成功。

其實在ibtias框架裏使用selectkey這個節點,並設置insert返回值的類型爲integer,就能夠返回這個id值。

相關文章
相關標籤/搜索