Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 对于UUID类型列,在插入新行时返回H2数据库中默认生成的主键值_Java_Sql_Jdbc_H2_Uuid - Fatal编程技术网

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

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

当使用数据作为表的主键,并要求H2在插入新记录时,如何访问新生成的UUID值

我在Java应用程序中使用纯JDBC4.x,如果这对解决方案有帮助的话


我知道函数返回一个
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,我也从你那里学到了很多:)