Перейти к основному содержимому

Возврат сгенерированных ключей в JDBC

· 3 мин. чтения

1. Обзор

В этом кратком руководстве мы увидим, как мы можем получить последние автоматически сгенерированные ключи с помощью чистого JDBC.

2. Настройка

Чтобы иметь возможность выполнять SQL-запросы, мы собираемся использовать базу данных H2 в памяти .

Итак, для нашего первого шага давайте добавим его зависимость от Maven:

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

Кроме того, мы будем использовать очень простую таблицу всего с двумя столбцами:

public class JdbcInsertIdIntegrationTest {

private static Connection connection;

@BeforeClass
public static void setUp() throws Exception {
connection = DriverManager.getConnection("jdbc:h2:mem:generated-keys", "sa", "");
connection
.createStatement()
.execute("create table persons(id bigint auto_increment, name varchar(255))");
}

@AfterClass
public static void tearDown() throws SQLException {
connection
.createStatement()
.execute("drop table persons");
connection.close();
}

// omitted
}

Здесь мы подключаемся к базе данных сгенерированных ключей ` в памяти и создаем в ней таблицу с именем person` .

3. Флаг возврата сгенерированных ключей

Один из способов получить ключи после автоматической генерации — передать Statement.RETURN_GENERATED_KEYS в метод prepareStatement() :

String QUERY = "insert into persons (name) values (?)";
try (PreparedStatement statement = connection.prepareStatement(QUERY, Statement.RETURN_GENERATED_KEYS)) {
statement.setString(1, "Foo");
int affectedRows = statement.executeUpdate();
assertThat(affectedRows).isPositive();

// omitted
} catch (SQLException e) {
// handle the database related exception appropriately
}

После подготовки и выполнения запроса мы можем вызвать метод getGeneratedKeys() для PreparedStatement , чтобы получить идентификатор:

try (ResultSet keys = statement.getGeneratedKeys()) {
assertThat(keys.next()).isTrue();
assertThat(keys.getLong(1)).isGreaterThanOrEqualTo(1);
}

Как показано выше, мы сначала вызываем метод next() для перемещения курсора результата. Затем мы используем метод getLong() , чтобы получить первый столбец и одновременно преобразовать его в длинный .

Более того, ту же технику можно использовать и с обычными операторами :

try (Statement statement = connection.createStatement()) {
String query = "insert into persons (name) values ('Foo')";
int affectedRows = statement.executeUpdate(query, Statement.RETURN_GENERATED_KEYS);
assertThat(affectedRows).isPositive();

try (ResultSet keys = statement.getGeneratedKeys()) {
assertThat(keys.next()).isTrue();
assertThat(keys.getLong(1)).isGreaterThanOrEqualTo(1);
}
}

Кроме того, стоит упомянуть, что мы широко используем try-with-resources , чтобы позволить компилятору убирать за нами.

4. Возврат столбцов

Оказывается, мы также можем попросить JDBC вернуть определенные столбцы после выдачи запроса . Для этого нам просто нужно передать массив имен столбцов:

try (PreparedStatement statement = connection.prepareStatement(QUERY, new String[] { "id" })) {
statement.setString(1, "Foo");
int affectedRows = statement.executeUpdate();
assertThat(affectedRows).isPositive();

// omitted
}

Как показано выше, мы говорим JDBC вернуть значение столбца id после выполнения данного запроса. Как и в предыдущем примере, мы можем получить идентификатор позже:

try (ResultSet keys = statement.getGeneratedKeys()) {
assertThat(keys.next()).isTrue();
assertThat(keys.getLong(1)).isGreaterThanOrEqualTo(1);
}

Мы можем использовать тот же подход и с простыми операторами :

try (Statement statement = connection.createStatement()) {
int affectedRows = statement.executeUpdate("insert into persons (name) values ('Foo')",
new String[] { "id" });
assertThat(affectedRows).isPositive();

try (ResultSet keys = statement.getGeneratedKeys()) {
assertThat(keys.next()).isTrue();
assertThat(keys.getLong(1)).isGreaterThanOrEqualTo(1);
}
}

5. Вывод

В этом кратком руководстве мы увидели, как мы можем получить сгенерированные ключи после выполнения запроса с помощью чистого JDBC.

Как обычно, все примеры доступны на GitHub .