Spring JDBCで自動生成キーを取得する

Spring JDBCで自動生成キーを取得する

1. 前書き

このクイックチュートリアルでは、Spring JDBCを操作するときにエンティティを挿入した後、自動生成されたキーを取得する可能性について説明します。

2. Mavenの依存関係

最初に、pom.xmlspring-boot-starter-jdbc H2の依存関係を定義する必要があります。


    org.springframework.boot
    spring-boot-starter-jdbc


    com.h2database
    h2
    runtime

Maven Centralの2つの依存関係の最新バージョンであるspring-boot-starter-jdbch2を確認できます。

3. 自動生成されたキーの取得

3.1. シナリオ

id(自動生成されたキー)とmessageの2つの列を持つsys_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. 結論

JDBCTemplateSimpleJdbcInsertを使用して新しいレコードを挿入し、自動生成されたキーを元に戻す可能性を検討しました。

いつものように、この記事over on Githubの実装を見つけることができます。