バージョン
- Spring Framework 6.1
- Spring Boot 3.2
JdbcClientって?
Spring Framework 6.1(対応するSpring Bootは3.2)からJdbcClient
インタフェースが導入されました。
内部的にはJdbcTemplate
およびNamedParameterJdbcTemplate
のラッパーです。
流れるようなインタフェース(Fluent API)が特徴です。
Optionalが使いやすい
JdbcTemplate
で主キー検索してその結果を何かのクラスのOptional
にしたい場合、👇のようにちょっと面倒でした。
JdbcTemplateでOptionalを返す例
public Optional<Hoge> selectById(Integer id) {
try {
Hoge hoge = jdbcTemplate.queryForObject("""
SELECT id, name
FROM hoge WHERE id = ?
""", new DataClassRowMapper<>(Hoge.class), id);
return Optional.of(hoge);
} catch (EmptyResultDataAccessException e) {
return Optional.empty();
}
}
これがJdbcClient
だと👇のように書けます。
JdbcClientでOptionalを返す例
public Optional<Hoge> selectById(Integer id) {
Optional<Hoge> hogeOp = jdbcClient.sql("""
SELECT id, name
FROM hoge WHERE id = ?
""")
.param(id)
.query(new DataClassRowMapper<>(Hoge.class))
.optional();
return hogeOp;
}
例外をキャッチする必要が無いのでスッキリですね!
KeyHolderが使いやすい
INSERTした時にDBで自動生成された主キー値(PostgreSQLのシーケンスなどが使われている場合)を取得するにはKeyHolder
を使う必要があります。JdbcTemplate
の場合、PreparedStatement
を操作する必要があって面倒でした。
JdbcTemplateでKeyHolderを使う例
public Hoge insert(Hoge hoge) {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcTemplate.update(connection -> {
PreparedStatement statement = connection.prepareStatement("""
INSERT INTO hoge(name)
VALUES(?)
""", new String[]{"id"});
statement.setString(1, hoge.name());
return statement;
}, keyHolder);
int newId = keyHolder.getKey().intValue();
return new Hoge(newId, hoge.name());
}
JdbcClient
ではupdate()
の引数にKeyHolder
と主キー列名を渡すだけで済みます。主キー列名が配列ではなく可変長引数になっているのも嬉しいですね!
JdbcClientでKeyHolderを使う例
public Hoge insert(Hoge hoge) {
KeyHolder keyHolder = new GeneratedKeyHolder();
jdbcClient.sql("""
INSERT INTO hoge(name)
VALUES(?)
""")
.param(hoge.name())
.update(keyHolder, "id");
int newId = keyHolder.getKey().intValue();
return new Hoge(newId, hoge.name());
}