Java 对于UUID类型列,在插入新行时返回H2数据库中默认生成的主键值
当使用数据作为表的主键,并要求H2在插入新记录时,如何访问新生成的UUID值 我在Java应用程序中使用纯JDBC4.x,如果这对解决方案有帮助的话Java 对于UUID类型列,在插入新行时返回H2数据库中默认生成的主键值,java,sql,jdbc,h2,uuid,Java,Sql,Jdbc,H2,Uuid,当使用数据作为表的主键,并要求H2在插入新记录时,如何访问新生成的UUID值 我在Java应用程序中使用纯JDBC4.x,如果这对解决方案有帮助的话 我知道函数返回一个long,用于在标记为IDENTITY的列上为自动递增序列号生成的键。但我使用UUID而不是递增的数字作为主键列类型。指定生成列的名称 在准备语句时,您可以选择传递正在为其生成默认值的列的名称数组。对于单个主键列,这意味着一个值的数组 请参见方法: 示例代码 // here you can specify the list of
我知道函数返回一个
long
,用于在标记为IDENTITY
的列上为自动递增序列号生成的键。但我使用UUID而不是递增的数字作为主键列类型。指定生成列的名称
在准备语句时,您可以选择传递正在为其生成默认值的列的名称数组。对于单个主键列,这意味着一个值的数组
请参见方法:示例代码
// 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
,如的文档中所述
通用唯一标识符。这是一个128位的值。储存
值,使用PreparedStatement.setBytes、setString或setObject(uuid)
(其中uuid是java.util.uuid)ResultSet.getObject将返回一个
java.util.UUID.
我的示例基于您在问题中共享的链接
语句::getGeneratedKeys
如注释和中所示,解决方案在于标准的JDBC:Call。这将生成在先前使用该语句时默认生成的键值的一部分。这适用于自动生成UUID值作为主键
语句。返回生成的密钥
问题是,默认情况下,您不会返回生成的密钥。必须通过向调用传递额外参数来激活此功能。额外的参数是一个int
,使用语句
接口上定义的常量。在现代Java中,这很可能被定义为,但可以追溯到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
信息-报告表中的所有行人员
人员:9c6ce984-151b-4e64-8334-d96e17be9525 |杰西·约翰逊
如果希望一次插入多行,而不是一行,请使用批处理。请参阅:
如果您有多个自动生成的列,而不是这里看到的一个UUID列,请参阅。您使用的是spring数据还是简单的JDBC?@YCF\L Straight JDBC,也不是ORM,没有其他框架。您尝试过吗?这是JDBC中可用的基本方法。@krokodilko谢谢,使用标准的JDBC做到了这一点。在我和YCF_L的回答中解释。这个问题与另一个问题非常接近,但这里的这个问题是专门针对H2数据库引擎的:和往常一样,我忘了使用rs.getObject(1,UUID.class)代码>:)谢谢你教育我。回答很好,但我认为在大多数情况下,我们只有一个自动生成的列,我的答案中的方法更简单,调用这个(int的第二个参数)而不是那个(array的第二个参数)。欢迎@Basil Bourque,我也从你那里学到了很多:)