Spring JDBCでデータを1件取得したい場合に、0件の場合がある場合はどうするか?


jdbcTemplate#queryForObject(sql,rowMapper)というメソッドがあります。
これは、対象のSQLによって必ず一件のレコードが返る場合はうまく動きますが、投げたsqlの結果が0件のときは実行時エラーを返します。


@Repository
public class ArticleDao implements ArticleDaoSpec {

	@Autowired
	private NamedParameterJdbcTemplate template;

        @Override
	public ArticleDto findOne(String articleId) {
		String sql = "SELECT * FROM article WHERE article_id=:articleId";
		return template.queryForObject(sql, new MapSqlParameterSource().addValue("articleId", articleId), (rs, i) -> {
			ArticleDto dto = new ArticleDto();
			dto.setArticleId(rs.getInt("article_id"));
			dto.setUserId(rs.getString("user_id"));
			dto.setContents(rs.getString("contents"));
			dto.setPostDate(rs.getTimestamp("post_date"));
			return dto;
		});
	}
}

上記のコードは、SQLの結果必ず1件の結果が変えることが保証されていないと0件のときに実行時エラーになります。
ところが、「SQLの結果は1件か0件」というケースは意外によくあるので、このままだと都合が悪かったりします。

これに対処する方法はいくつかあると思いますが、私はjava8のOptionalを使って、



@Repository
public class ArticleDao implements ArticleDaoSpec {

	@Autowired
	private NamedParameterJdbcTemplate template;

        @Override
	public Optional<ArticleDto> optionalFindOne(String articleId) {
		String sql = "SELECT * FROM article WHERE article_id=:articleId";
		List<ArticleDto> result = template.query(sql, new MapSqlParameterSource().addValue("articleId", articleId),
				(rs, i) -> {
					ArticleDto dto = new ArticleDto();
					dto.setArticleId(rs.getInt("article_id"));
					dto.setUserId(rs.getString("user_id"));
					dto.setContents(rs.getString("contents"));
					dto.setPostDate(rs.getTimestamp("post_date"));
					return dto;
				});
		return result.isEmpty() ? Optional.empty() : Optional.of(result.get(0));
	}

}

と書きます。

さらに、「Optionalで0件か1件の結果を返す」という切り方で抽象化して、


public abstract class OptionalFinder<T> {

	public Optional<T> findOne(NamedParameterJdbcTemplate template, String sql, MapSqlParameterSource paramMap,
			RowMapper<T> rowMapper) {
		List<T> result = template.query(sql, paramMap, rowMapper);
		return result.isEmpty() ? Optional.empty() : Optional.of(result.get(0));
	}

}

という風な共通ロジッククラスを定義し、これを継承することも考えられます。(引数にtemplate渡しちゃうのは多少筋が悪いですが。。。)
他に良い書き方あるんだろうか。。。