[英]Return primary key value generated by default in H2 database upon INSERT of new row, for UUID type column
當使用UUID數據類型作為表的主鍵時,並要求H2在插入新記錄時默認生成每個UUID值,如何訪問新生成的UUID值的值?
我在 Java 應用程序中使用純 JDBC 4.x,如果這有助於解決方案。
我知道SCOPE_IDENTITY
函數返回一個long
用於在標記為IDENTITY
的列上生成的鍵,用於自動遞增序列號。 但我使用 UUID 而不是遞增數字作為我的主鍵列類型。
准備語句時,您可以選擇傳遞為其生成默認值的列的名稱數組。 對於您的單個主鍵列,這意味着一個值的數組。
見方法:
Connection::prepareStatement( String sql, String[] columnNames )
示例代碼。
// here you can specify the list of returned attributes, in your case just the data
String[] returnedAttributes = {"data"};
String insertQuery = "insert into test(id) values(1);";
try
(
PreparedStatement insertStatement = conn.prepareStatement(insertQuery, returnedAttributes);
)
{
int rows = insertStatement.executeUpdate();
if (rows == 0)
{
throw new SQLException("Failed of insertion");
}
try (ResultSet rs = insertStatement.getGeneratedKeys()) {
if (rs.next())
{
java.util.UUID uuid = (java.util.UUID) rs.getObject("data");
System.out.println(uuid);
}
}
}
筆記
要獲取 UUID 類型,您必須使用getObjct(..)
並將其轉換為java.util.UUID
,如H2 UUID 類型文檔中所述
通用唯一標識符。 這是一個 128 位的值。 要存儲值,請使用 PreparedStatement.setBytes、setString 或 setObject(uuid)(其中 uuid 是 java.util.UUID)。 ResultSet.getObject 將返回一個 java.util.UUID。
我的示例基於您在問題中共享的鏈接Generate UUID values by default for each row on column of UUID type in H2 Database Engine
Statement::getGeneratedKeys
正如YCF_L 的評論和正確答案中所見,解決方案在於標准 JDBC:Call Statement::getGeneratedKeys
。 這將生成一個ResultSet
,其中包含在先前使用該語句時默認生成的鍵值。 這適用於PreparedStatement
,並使用自動生成的 UUID 值作為主鍵。
Statement.RETURN_GENERATED_KEYS
問題是默認情況下您不會取回生成的密鑰。 您必須通過將額外參數傳遞給Connection::prepareStatement
調用來激活此功能。 額外的參數是一個int
,使用在Statement
接口上定義的常量Statement.RETURN_GENERATED_KEYS
。 在現代 Java 中,它可能被定義為Enum
,但JDBC可以追溯到 Java 的早期,因此參數是一個簡單的int
。
這是一個完整的示例應用程序,位於單個文件中。
package work.basil.example.h2.auto_uuid;
import java.sql.*;
import java.util.UUID;
public class App {
public static void main ( String[] args ) {
App app = new App();
app.doIt();
}
private void doIt ( ) {
try {
Class.forName( "org.h2.Driver" );
} catch ( ClassNotFoundException e ) {
e.printStackTrace();
}
try (
Connection conn = DriverManager.getConnection( "jdbc:h2:mem:auto_uuid_example_db;DB_CLOSE_DELAY=-1" ) ; // Set `DB_CLOSE_DELAY` to `-1` to keep in-memory database in existence after connection closes.
Statement stmt = conn.createStatement() ;
) {
String sql = "CREATE TABLE person_ ( \n" +
" pkey_ UUID NOT NULL DEFAULT RANDOM_UUID() PRIMARY KEY , \n" +
" name_ VARCHAR NOT NULL \n" +
");";
stmt.execute( sql );
// Insert row.
sql = "INSERT INTO person_ ( name_ ) \n";
sql += "VALUES ( ? ) \n";
sql += ";";
try (
PreparedStatement pstmt = conn.prepareStatement( sql , Statement.RETURN_GENERATED_KEYS ) ;
) {
pstmt.setString( 1 , "Jesse Johnson" );
pstmt.executeUpdate();
ResultSet rs = pstmt.getGeneratedKeys();
System.out.println( "INFO - Reporting generated keys." );
while ( rs.next() ) {
UUID uuid = rs.getObject( 1 , UUID.class );
System.out.println( "generated keys: " + uuid );
}
}
// Dump all rows.
System.out.println( "INFO - Reporting all rows in table `person_`." );
sql = "SELECT * FROM person_";
try ( ResultSet rs = stmt.executeQuery( sql ) ; ) {
while ( rs.next() ) {
UUID pkey = rs.getObject( "pkey_" , UUID.class );
String name = rs.getString( "name_" );
System.out.println( "Person: " + pkey + " | " + name );
}
}
} catch ( SQLException e ) {
e.printStackTrace();
}
}
}
運行時。
信息 - 報告生成的密鑰。
生成的密鑰:9c6ce984-151b-4e64-8334-d96e17be9525
INFO - 報告表
person_
中的所有行。人:9c6ce984-151b-4e64-8334-d96e17be9525 | 傑西約翰遜
如果要一次插入多行而不是一行,請使用批處理。 請參閱: Java:使用 PreparedStatement 將多行插入 MySQL 。
如果您有多個自動生成的列,而不是這里看到的只有一個 UUID 列,請參閱YCF_L 的另一個答案。
要從結果集中返回 UUID,您可以使用 FINAL TABLE:
SELECT ID FROM FINAL TABLE ( INSERT INTO PERSON(NAME) VALUES('Joe'))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.