对于新的UUID类型列,在插入新行后返回H2数据库中默认生成的主键值

时间:2018-12-23 20:45:32

标签: java sql jdbc h2 uuid

使用UUID数据type作为表的主键,并在插入新记录时要求H2 generate each UUID value by default时,如何访问该值新生成的UUID值

如果有解决方案,我正在Java应用程序中使用纯JDBC 4.x。


我知道SCOPE_IDENTITY函数为在自动递增序列号标记为long的列上生成的密钥返回IDENTITY。但是我使用UUID而不是递增数字作为主键列类型。

2 个答案:

答案 0 :(得分:3)

指定生成的列的名称

在准备语句时,可以选择传递要为其生成默认值的列名称的数组。仅对于单个主键列,这意味着一个值的数组。

请参见方法:
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(..)并将其转换为H2 UUID Type文档中所述的java.util.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中共享的链接

答案 1 :(得分:2)

Statement::getGeneratedKeys

从注释和correct Answer by YCF_L中可以看出,解决方案在于标准的JDBC:调用Statement::getGeneratedKeys。这将产生ResultSet的键值,该键值是在该语句的先前使用中默认生成的。这适用于PreparedStatement,并且适用于自动生成UUID值作为主键。

Statement.RETURN_GENERATED_KEYS

要注意的是,默认情况下,您不执行 not 来获取生成的密钥。您必须通过向您的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();
        }


    }
}

运行时。

  

INFO-报告生成的密钥。

     

生成的密钥:9c6ce984-151b-4e64-8334-d96e17be9525

     

INFO-报告表person_中的所有行。

     

人员:9c6ce984-151b-4e64-8334-d96e17be9525 |杰西·约翰逊(Jesse Johnson)

如果要一次而不是一次插入多行,请使用批处理。请参阅:Java: Insert multiple rows into MySQL with PreparedStatement

如果您要自动生成多个列,而不仅仅是此处看到的一个UUID列,请参见other Answer by YCF_L