在 JDBC 中获取插入 ID

使用JDBC将数据插入数据库时​​,检索自动生成的主键是一项常见要求。JDBC 提供了一种在插入操作后立即获取插入 ID 的机制:JDBC 可以使用getGeneratedKeys()方法获取插入 ID

本教程讨论如何在插入操作后立即获取插入 ID。

设置
在讨论和实现获取插入 ID 的逻辑之前,我们首先讨论必要的设置步骤。

为了测试我们的实现,我们将使用内存中的H2数据库。我们可以在pom.xml文件中添加h2数据库依赖项:

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

在我们的测试设置中,我们可以连接到 H2 数据库并使用我们的示例表(即员工表)填充数据库。

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();
}


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

要插入记录,我们可以使用preparedStatement.executeUpdate(),它返回更新的行数。要获取插入ID,我们可以使用Statement.RETURN_GENERATED_KEYS:

String sql = "INSERT INTO employees (first_name, last_name, salary) VALUES (?, ?, ?)";
PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
statement.setString(1,
"first");
statement.setString(2,
"last");
statement.setDouble(3, 100.0);
int numRows = statement.executeUpdate();

现在,我们可以调用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中检索第一个生成的键。如果插入操作生成多个生成的键,我们可以使用它们各自的位置来访问它们。例如,getLong(2)将获取行中的第二个生成的键,getLong(3)将获取第三个生成的键,依此类推。此外,我们还可以使用列标签访问生成的键,例如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);
}