はじめてのSpringBoot8 ~JDBC:名前付き変数と検索結果0件~

3 min read読了の目安(約3200字

はじめに

はじめまして
私はJavaを研修で少しかじった程度でSpringBootを使用した開発に参加し、てんやわんやしております森田和華です。
全く分からない中から少しずつ調べて実装をしていますが、自分の学習の為にも記事にして残しておこうと思い作成しております。
参考にしていただける際はそのあたりを念頭に置いたうえで参考にしていただければと思います。
もし私の記事を読んでおかしなところなどありましたらご指摘いただけると嬉しいです。

環境

SpringBootバージョン:2.4.0
Javaバージョン:8
DB:MySQL 8.0
IDE:eclipse

今回の目標

今回は前回の
・queryForObject
・queryForMap
・queryForList
勉強中に気になっていた。
1.パラメータバインドを名前付き変数にする(?だとSQLの可読性が低いから)
2.検索結果が0件の時はどうなるのか(エラー?null?)
について調べます。

パラメータバインドを名前付き変数にする

NamedParameterJdbcTemplateクラス

実はJdbcTemplateとは別にもう一つ、NamedParameterJdbcTemplateがあることはサラッと触れただけになっていましたが、こちらを使用するとパラメータを「?」で指定するのではなくパラメータ名をつけて個別に設定出来るようです。
パラメータの命名の利点と欠点は以下になります。
<パラメータを命名する利点>
・複数パラメータを持つ場合、順序を意識しなければならずミスが発生しやすい
・可読性が低下する
<パラメータを命名する欠点>
・記述コード量が増える

実装してみる

JDBCtestRepository.java
//追記部分のみ記載
@Autowired
NamedParameterJdbcTemplate namedParameterJdbcTemplate;

//指定方法その1(Map指定)
//パラメータ一つだと簡単に実装できる
public String findTitleByIdNameParam1(int id){

	String sql ="SELECT title FROM book_sample where id = :id"; //バインドパラメータは:カラム名で指定
	Map<String,Object> params =new HashMap<String,Object>();	
	params.put("id", id); //カラム名とパラメータをセット
	return namedParameterJdbcTemplate.queryForObject(sql,params,String.class);//第二引数でパラメータを指定
}

//指定方法その2(MapSqlParameterSource指定)
//パラメータが複数の時には簡単に実装できる
public String findTitleByIdNameParam2(int id,int delflg){
	String sql ="SELECT title FROM book_sample where id = :id and delflg= :delflg"; //バインドパラメータは:カラム名で指定
	MapSqlParameterSource map = new MapSqlParameterSource()
		.addValue("id",id)
		.addValue("delflg", delflg);
	return namedParameterJdbcTemplate.queryForObject(sql,map,String.class);//第二引数でパラメータを指定
}

//指定方法その3(BeanPropertySqlParameterSource指定)
//オブジェクトのプロパティをそのまま使うときは簡単に使える
public String findTitleByIdNameParam3(int id,int delflg){

	String sql ="SELECT title FROM book_sample where id = :id and delflg= :delflg"; //バインドパラメータは:カラム名で指定
	BookEntity bookentity = new BookEntity(id,"title","summary","classification",delflg);
	BeanPropertySqlParameterSource map = new BeanPropertySqlParameterSource(bookentity);
	return namedParameterJdbcTemplate.queryForObject(sql,map,String.class);//第二引数でパラメータを指定
}
SampleContoroller.java
//追記部分のみ記載
model.addAttribute("title1",jdbcTestRepository.findTitleByIdNameParam1(1));
model.addAttribute("title2",jdbcTestRepository.findTitleByIdNameParam2(1,0));
model.addAttribute("title3",jdbcTestRepository.findTitleByIdNameParam3(1,0));
sample.html
//追記部分のみ記載
<div th:if="${title1 ne null}" th:text="'title1は'+${title1}" ></div>
<div th:if="${title2 ne null}" th:text="'title2は'+${title2}" ></div>
<div th:if="${title3 ne null}" th:text="'title3は'+${title3}" ></div>

動作確認

選択部分が今回の表示部分。無事表示されています。

それぞれ扱いたいパラメータのデータでどの方法を使うか考えた方がよさそうです。

検索結果が0件の時はどうなるのか

これはメソッドで処理が異なるようです。
・queryForList
空のリストが返却され例外の発生はなし

・queryForList以外
JdbcTemplateの処理が呼ばれる前にSpringが例外をスローします。
そのためResultSetExtractorを利用する場合を除きデータは存在する前提で実装することになります。
0件時にスローされる例外はEmptyResultDataAccessExceptionです。

次回

次回は
・updateメソッド
の使用方法について調べていきたいと思います。

参考文献

Spring徹底入門 Spring FrameworkによるJavaアプリケーション開発 (著 株式会社NTTデータ)

https://www.shoeisha.co.jp/book/detail/9784798142470