Получение автоматически сгенерированных ключей в Spring JDBC
1. Вступление
В этом кратком руководстве мы рассмотрим возможность получения автоматически сгенерированного ключа после вставки сущностей при работе сSpring JDBC.
2. Maven Зависимости
Сначала нам нужно определить зависимостиspring-boot-starter-jdbc andH2 в нашемpom.xml:
org.springframework.boot
spring-boot-starter-jdbc
com.h2database
h2
runtime
Мы можем проверить последнюю версию этих двух зависимостей на Maven Central:spring-boot-starter-jdbc иh2.
3. Получение автоматически сгенерированного ключа
3.1. Сценарий
Давайте определим таблицуsys_message, которая имеет 2 столбца:id (автоматически сгенерированный ключ) иmessage:
CREATE TABLE IF NOT EXISTS sys_message (
id bigint(20) NOT NULL AUTO_INCREMENT,
message varchar(100) NOT NULL,
PRIMARY KEY (id)
);
3.2. ИспользуяJdbcTemplate
Теперь давайте реализуем метод, который будет использоватьJDBCTemplate для вставки новой записи и возврата автоматически сгенерированногоid.
Следовательно, методwe’ll use the JDBCTemplate update(), который поддерживает получение первичных ключей, сгенерированных базой данных. Этот метод принимает экземпляр интерфейсаPrepareStatementCreator в качестве первого аргумента, а другим аргументом являетсяKeyHolder.
Поскольку интерфейсPrepareStatementCreator - этоFunctionalInterface , его метод принимает экземплярjava.sql.Connection и возвращает объектjava.sql.PreparedStatement, для простоты мы можем использовать лямбда-выражение:
String INSERT_MESSAGE_SQL
= "insert into sys_message (message) values(?) ";
public long insertMessage(String message) {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement ps = connection
.prepareStatement(INSERT_MESSAGE_SQL);
ps.setString(1, message);
return ps;
}, keyHolder);
return (long) keyHolder.getKey();
}
}
It’s worth noting that the keyHolder object will contain the auto-generated key return from the JDBCTemplate update() method.
Мы можем получить этот ключ, вызвавkeyHolder.getKey().
Кроме того, мы можем проверить метод:
@Test
public void
insertJDBC_whenLoadMessageByKey_thenGetTheSameMessage() {
long key = messageRepositoryJDBCTemplate.insert(MESSAGE_CONTENT);
String loadedMessage = messageRepositoryJDBCTemplate
.getMessageById(key);
assertEquals(MESSAGE_CONTENT, loadedMessage);
}
3.3. ИспользуяSimpleJdbcInsert
В дополнение кJDBCTemplate, мы также можем использоватьSimpleJdbcInsert для достижения того же результата.
Следовательно, нам нужно инициализировать экземплярSimpleJdbcInsert:
@Repository
public class MessageRepositorySimpleJDBCInsert {
SimpleJdbcInsert simpleJdbcInsert;
@Autowired
public MessageRepositorySimpleJDBCInsert(DataSource dataSource) {
simpleJdbcInsert = new SimpleJdbcInsert(dataSource)
.withTableName("sys_message").usingGeneratedKeyColumns("id");
}
//...
}
Следовательно,we can call the executeAndReturnKey method of the SimpleJdbcInsert to insert a new record to sys_message table and get back the auto-generated key:
public long insert(String message) {
Map parameters = new HashMap<>(1);
parameters.put("message", message);
Number newId = simpleJdbcInsert.executeAndReturnKey(parameters);
return (long) newId;
}
Кроме того, мы можем проверить этот метод довольно просто:
@Test
public void
insertSimpleInsert_whenLoadMessageKey_thenGetTheSameMessage() {
long key = messageRepositorySimpleJDBCInsert.insert(MESSAGE_CONTENT);
String loadedMessage = messageRepositoryJDBCTemplate.getMessageById(key);
assertEquals(MESSAGE_CONTENT, loadedMessage);
}
4. Заключение
Мы изучили возможность использованияJDBCTemplate иSimpleJdbcInsert для вставки новой записи и возврата автоматически сгенерированного ключа.
Как всегда, мы можем найти реализацию этой статьиover on Github.