JDBC INSERT 返回自增 Id

1、简介

在使用 JDBC 向数据库插入数据时,如果主键 ID 是自增的,那么我们需要获取到新插入的这条数据的 ID。JDBC 提供了一种在 INSERT 操作后立即获取其自增 ID 的机制。

2、示例项目

为了方便测试,本例使用H2 内存数据库。

pom.xml 文件中添加 h2 数据库依赖:

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.1.214</version>
</dependency>

首先,连接到 H2 数据库,并在数据库中创建 EMPLOYEES 测试表:

private static void populateDB() throws SQLException {
    String createTable = """
        CREATE TABLE EMPLOYEES (
            id SERIAL PRIMARY KEY ,
            first_name VARCHAR(50),
            last_name VARCHAR(50),
            salary DECIMAL(10, 2)
        );
        """;
    PreparedStatement preparedStatement = connection.prepareStatement(createTable);
    preparedStatement.execute();
}

3、检索自增 ID

执行 INSERT 语句时,如果表有自动生成的键(如 MySQL 中的 AUTO_INCREMENT、PostgreSQL 中的 SERIAL 或 H2 数据库中的 IDENTITY),JDBC 可以使用 getGeneratedKeys() 方法检索这些键。

通常,我们会使用 preparedStatement.executeUpdate() 来执行 INSERT SQL 语句,它会返回更新的记录数。要获取自增 ID,可以使用 Statement.RETURN_GENERATED_KEYS 参数:

String sql = "INSERT INTO employees (first_name, last_name, salary) VALUES (?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql,
    // 要求返回自增 KEY 的值
 Statement.RETURN_GENERATED_KEYS);
 
statement.setString(1, "first");
statement.setString(2, "last");
statement.setDouble(3, 100.0);

// 受影响的行数
int numRows = statement.executeUpdate();

SQL 执行完毕后,可以调用 statement.getGeneratedKeys() 来获取 ResultSet,这样就可以使用 getLong() 来获取自增的 ID:

ResultSet generatedKeys = statement.getGeneratedKeys();
List<Long> insertIds = new ArrayList<>();
while(generatedKeys.next()){
    insertIds.add(generatedKeys.getLong(1));
 }

如上,getLong(1) 表示从 ResultSet 中检索第一个自动生成的 KEY。如果 insert 操作生成了多个 KEY,则可以通过索引访问它们。例如,getLong(2) 将获取行中第二个生成的 KEY,getLong(3) 获取第三个生成的 KEY,以此类推。此外,还可以使用列名访问生成的键,例如,getLong("id1")getLong("id2"),等等。

通过单元测试来验证结果:

@Test
public void givenDBPopulated_WhenGetInsertIds_ThenReturnsIds() throws SQLException {
    GetInsertIds getInsertIds = new GetInsertIds();
    List<Long> actualIds = getInsertIds.insertAndReturnIds(connection);
    ResultSet resultSet = connection.prepareStatement("select id from employees").executeQuery();
    List<Long> expectedIds = new ArrayList<>();
    while (resultSet.next()){
        expectedIds.add(resultSet.getLong(1));
    }

    assertEquals(expectedIds, actualIds);
}

4、总结

本文介绍了如何在使用 JDBC PreparedStatement 执行 INSERT 插入时获取到其自增的 ID。


Ref:https://www.baeldung.com/jdbc-get-insert-id