使用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); }
|