Obtendo chaves geradas automaticamente no Spring JDBC
1. Introdução
Neste tutorial rápido, exploraremos a possibilidade de obter a chave gerada automaticamente após inserir entidades ao trabalhar comSpring JDBC.
2. Dependências do Maven
Primeiramente, precisamos terspring-boot-starter-jdbc andH2 dependências definidas em nossopom.xml:
org.springframework.boot
spring-boot-starter-jdbc
com.h2database
h2
runtime
Podemos verificar a versão mais recente dessas duas dependências no Maven Central:spring-boot-starter-jdbceh2.
3. Obtendo a chave gerada automaticamente
3.1. O cenário
Vamos definir uma tabelasys_message que tem 2 colunas:id (chave gerada automaticamente) emessage:
CREATE TABLE IF NOT EXISTS sys_message (
id bigint(20) NOT NULL AUTO_INCREMENT,
message varchar(100) NOT NULL,
PRIMARY KEY (id)
);
3.2. Usando oJdbcTemplate
Agora, vamos implementar um método que usaráJDBCTemplate para inserir o novo registro e retornar oid. gerado automaticamente
Portanto, o métodowe’ll use the JDBCTemplate update() que suporta a recuperação de chaves primárias geradas pelo banco de dados. Este método usa uma instância da interfacePrepareStatementCreator como o primeiro argumento e o outro argumento é oKeyHolder.
Como a interfacePrepareStatementCreator é umFunctionalInterface onde seu método aceita uma instância dejava.sql.Connectione retorna um objetojava.sql.PreparedStatement, para simplificar, podemos usar uma expressão lambda:
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.
Podemos recuperar essa chave chamandokeyHolder.getKey().
Além disso, podemos verificar o método:
@Test
public void
insertJDBC_whenLoadMessageByKey_thenGetTheSameMessage() {
long key = messageRepositoryJDBCTemplate.insert(MESSAGE_CONTENT);
String loadedMessage = messageRepositoryJDBCTemplate
.getMessageById(key);
assertEquals(MESSAGE_CONTENT, loadedMessage);
}
3.3. UsandoSimpleJdbcInsert
Além deJDBCTemplate, também podemos usarSimpleJdbcInsert para obter o mesmo resultado.
Portanto, precisamos inicializar uma instância deSimpleJdbcInsert:
@Repository
public class MessageRepositorySimpleJDBCInsert {
SimpleJdbcInsert simpleJdbcInsert;
@Autowired
public MessageRepositorySimpleJDBCInsert(DataSource dataSource) {
simpleJdbcInsert = new SimpleJdbcInsert(dataSource)
.withTableName("sys_message").usingGeneratedKeyColumns("id");
}
//...
}
Consequentemente,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;
}
Além disso, podemos verificar esse método simplesmente:
@Test
public void
insertSimpleInsert_whenLoadMessageKey_thenGetTheSameMessage() {
long key = messageRepositorySimpleJDBCInsert.insert(MESSAGE_CONTENT);
String loadedMessage = messageRepositoryJDBCTemplate.getMessageById(key);
assertEquals(MESSAGE_CONTENT, loadedMessage);
}
4. Conclusão
Exploramos a possibilidade de usarJDBCTemplateeSimpleJdbcInsert para inserir um novo registro e obter a chave gerada automaticamente de volta.
Como sempre, podemos encontrar a implementação deste artigoover on Github.