SimpleJdbcInsert
やNamedParameterJdbcTemplate
などにパラメータを渡す際に用いるSqlParameterSource
ですが、このインターフェースと同じパッケージ(org.springframework.jdbc.core.namedparam
)には以下3種類の実装クラスが存在しています。
MapSqlParameterSource
BeanPropertySqlParameterSource
EmptySqlParameterSource
この記事ではこの3種類のSqlParameterSource
の使い方について書きます。
MapSqlParameterSource
マップ形式でパラメータを登録していくSqlParameterSource
です。
一番汎用的なものですが、場合によっては後述するBeanPropertySqlParameterSource
を使った方が省力化できます。
自分は主に引数をマップしていくような場面で使っています。
SELECT *
FROM hoge_table
WHERE hoge_id = :hogeId
AND hoge_status = :hogeStatus;
// 初期化は省略
String queryString;
NamedParameterJdbcTemplate jdbc;
BeanPropertyRowMapper<HogeDto> rowMapper;
public HogeDto selectHoge(Integer hogeId, String hogeStatus) {
MapSqlParameterSource param = new MapSqlParameterSource("hogeId", hogeId)
.addValue("hogeStatus", hogeStatus);
return jdbc.queryForObject(queryString, param, rowMapper);
}
BeanPropertySqlParameterSource
オブジェクトを入れるとパラメータとしてよしなに扱ってくれるSqlParameterSource
です。
自分は主にオブジェクトのフィールドの殆どでプリペアドステートメントを埋めたり、SimpleJdbcInsert
を使うような場合に使います。
UPDATE hoge_sub_value
SET hoge_value = :hogeValue
WHERE hoge_id = :hogeId
AND hoge_status = :hogeStatus
// 初期化は省略
String queryString;
NamedParameterJdbcTemplate jdbc;
public void updateHogeSubValues(List<HogeSubValue> subValues) {
BeanPropertySqlParameterSource[] params = subValues.stream()
.map(BeanPropertySqlParameterSource::new)
.toArray(SqlParameterSource[]::new);
jdbc.batchUpdate(queryString, params);
}
EmptySqlParameterSource
最後は、パラメータを使わないことを示すEmptySqlParameterSource
です。
NamedParameterJdbcTemplate
にはSqlParameterSource
の有無で別々のインターフェースが定義されていますが(e.g. <T> T query(String sql, SqlParameterSource paramSource, ResultSetExtractor<T> rse)
と<T> T query(String sql, ResultSetExtractor<T> rse)
)、以下の通り、内部的にはパラメータ有りの実装にEmptySqlParameterSource
を渡すという形で実装されています。
使う場面はあまり無いと思います。
@Override
@Nullable
public <T> T query(
String sql, SqlParameterSource paramSource, ResultSetExtractor<T> rse
) throws DataAccessException {
return getJdbcOperations().query(getPreparedStatementCreator(sql, paramSource), rse);
}
@Override
@Nullable
public <T> T query(
String sql, ResultSetExtractor<T> rse
) throws DataAccessException {
return query(sql, EmptySqlParameterSource.INSTANCE, rse);
}