Obtendo chaves geradas automaticamente no Spring JDBC

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.