[英]How to retrieve previously auto-generated PK ID value using JDBC and HSQLDB
我正在使用JDBC和HSQLDB 2.2.9。 將新行插入數據庫並隨后保留其id
(PK設置為自動增量)值的最有效和准確的方法是什么? 我需要這樣做的原因可能非常明顯,但我將舉例說明:
假設有一個Customer
表,其PersonId
字段的FK約束引用了Person
表中的一行。 我想創建一個新的Customer
,但為了做到這一點,我需要先創建一個新的Person
並使用新的Person.id
值來設置Customer.PersonId
。
我已經看到了四種方法:
將Person
行設置id
字段插入null
。 HSQLDB自動生成下一個id
值。 然后在Person
表上執行查詢以獲取剛剛創建的id
值,並使用它來創建新的Customer
行。
這對於檢索單個整數值來說似乎很昂貴。
獲取Person
表中的下一個id
值,並在INSERT
語句中使用它來手動設置Person.id
值。 使用相同的id
值來設置Customer.PersonId
。 不需要隨后從DB讀取。
如果獲得了id
值,則可能會出現不一致,但在執行INSERT INTO Person...
語句之前,另一個連接在表中執行INSERT
。
執行INSERT
語句,如上面的選項1所示,設置id=null
以允許自動生成。 然后使用getGeneratedKeys
方法檢索在最后一個語句中生成的鍵。
我覺得這聽起來像個不錯的選擇,但我無法讓它發揮作用。 這是我的代碼片段:
// PreparedStatement prepared previously... preparedStatement.executeUpdate(); ResultSet genKeys = preparedStatement.getGeneratedKeys(); int id; if (genKeys.next()) { id = genKeys.getInt(1); } // Finish up method...
此代碼為genKeys
返回一個空ResultSet
。 我錯誤地使用了getGeneratedKeys
方法嗎? 如果我可以讓它工作,這可能是要走的路。
再次,執行INSERT
語句,允許自動生成的id
。 然后立即執行CALL IDENTITY()
來獲取最后的id
值由連接產生的(如解釋在這里和在提到這個 SO問題)。
這似乎也是一個合理的選擇,即使我必須執行額外的executeQuery
。 從積極的方面來說,我實際上能夠使用以下代碼:
// INSERT statement executed here... statement = connection.createStatement(); ResultSet rs = statement.executeQuery("CALL IDENTITY();"); int id; if (rs.next()) id = rs.getInt(1); // Finish up method...
總而言之,前兩個選項我並不瘋狂。 第二個似乎沒問題,但我只能選擇4來工作。 哪個選項更受歡迎?為什么? 如果選項3是最好的,我做錯了什么? 還有,有沒有更好的方法,我沒有提到? 我知道像'更好'這樣的詞可以是主觀的,但我正在使用一個簡單的數據庫,並希望最直接的解決方案不會打開數據庫可能的不一致,並且不會增加事務失敗率(由於嘗試創建一個已經存在的id
的記錄。
這似乎是一個基本問題(也是必不可少的),但我找不到最佳方法的指導。 謝謝。
Statement.RETURN_GENERATED_KEYS
參數。
我沒有在我的代碼片段中顯示prepareStatement
方法,但我使用的是單參數版本。
我需要重試使用重載的雙參數版本。
還有一些其他SO問題出現在與我的問題密切相關的問題上。 所以,我想我的可能被視為重復(不知道我之前是否錯過了其他問題)。 但我仍然喜歡任何一個解決方案被認為比其他解決方案更好的指導。 現在,如果我讓選項3工作,我可能會繼續這樣做。
我沒有足夠的聲譽評論neizan的答案,但這是我如何解決同樣的問題:
使用HSQLDB 2.2.9的示例:
CREATE TABLE MY_TABLE (
ID INTEGER IDENTITY,
NAME VARCHAR(30)
)
然后在Java中:
PreparedStatement result = cnx.prepareStatement(
"INSERT INTO MY_TABLE(ID, NAME) VALUES(NULL, 'TOM');",
RETURN_GENERATED_KEYS);
int updated = result.executeUpdate();
if (updated == 1) {
ResultSet generatedKeys = result.getGeneratedKeys();
if (generatedKeys.next()) {
int key = generatedKeys.getInt(1);
}
}
這里行動不多,所以我會繼續回答這個問題。 在玩了不同的選項之后,在看到這個問題后,我能夠讓我的選項3工作。 就像我在編輯問題中提到的那樣,我將使用選項3.選項4也工作正常,但由於鏈接問題的接受答案是由信譽良好的來源提供的,所以我堅持這一點。 我希望在開始這個問題之前我已經看過那個問題/答案,我已經節省了一些時間!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.