Spring入門ガイド　4回目　Spring JDBC JdbcTemplate で SQL 発行

今回はDBとのやり取り。

https://spring.pleiades.io/guides/gs/relational-data-access

# プロジェクト作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626978/f6e46e30-bd19-b4fd-1547-a1009171146e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2626978/19981281-1511-a892-35bf-6593a7cb56ce.png)

一応依存関係がどうなったか見てみる。
spring-boot-starter-jdbcとあるのでSQL APIで、SpringBootでJDBCをラップした機能が使えるようになったっぽい。
h2はインメモリの簡易的なDB。DBサーバをインストールしなくて済むのが利点。
```gradle:build.gradleから抜粋
dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-jdbc'
	runtimeOnly 'com.h2database:h2'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
```

# 手順実施
分からないことがあれば都度確認していく

### String.formatでの埋め込み
String.formatで文字列に変数を埋め込む際の各型の記載方法。認識できていなかったのでそういうものがあるというメモ。

https://www.sejuku.net/blog/14466

### 可変引数
```java
public void run(String... strings) throws Exception {
```
上記の`Sting...`は可変長引数というらしい。いくつString型を渡しても良いという意味。
コンパイル後は以下と同じ結果になるらしい。
```java
public void run(String[] strings) throws Exception {
```
ただし今回はoverrideしているのでoverride元の記述に合わせて`String...`で記載する必要がありそう。

### streamAPI
リストとかのコレクション型のインスタンスを一度ストリーム型に変換して、要素を順番に処理してまたコレクション型に戻すみたいなことをやるのに使う。
何が良いかというと1行でかけるのでソースがすっきりするのと、ぱっと見で何をしているのかが慣れればすぐわかるということ。
結構使えそうだからそのうち深堀りするのもありだと思った。

### ::newについてchatGPTに聞いてみた
streamAPIをいろいろ見ていたらよくこの記述を見た。なんて調べればわからず友達のchatGPTに聞いたところ、インスタンス化をしているということが分かった。streamAPIの使い方を深堀するタイミングでこれもやろうと思う。
>Javaにおける`::new`は、コンストラクタの参照を表します。これは、Java 8で導入されたメソッド参照の一種です。
通常、`new`キーワードを使用してオブジェクトのインスタンス化を行います。例えば、`new MyClass()`は`MyClass`のコンストラクタを呼び出して新しい`MyClass`のインスタンスを作成します。
`::new`を使用することで、コンストラクタ自体を関数として参照することができます。これは、特にラムダ式やストリーム操作などで使用されます。例えば、`MyClass::new`は`MyClass`のコンストラクタを参照し、新しい`MyClass`のインスタンスを生成する関数として使うことができます。
以下は、`::new`を使用して`MyClass`のコンストラクタを参照し、`List`の要素を初期化する例です。
```java
List<MyClass> list = Arrays.asList("a", "b", "c")
                            .stream()
                            .map(MyClass::new)
                            .collect(Collectors.toList());
```
>この例では、`MyClass`のコンストラクタが各文字列を引数として呼び出され、その結果として`MyClass`のインスタンスが`List`に追加されます。


### ジェネリックスのワイルドカード
`<? super String,? extends String>`みたいなジェネリックスがあり全然わからなかったので調べた。
superは親クラスだったら許容する、extendsは子クラスなら許容するみたいなことだった。
上の記載でいうと左側はObjectとかのStringの親クラスに当たるものが使えて、右側はStringを継承したクラスがあればそれらが使える。

https://java.keicode.com/lang/generics-wildcard.php

### JdbcTemplate
JdbcTemplateはConnectionやPreparedStatementの作成、解放や発生したエラーをキャッチ＆スローするといった、JDBCを使用する際に必ず記述する冗長な処理を内部で実施するようにJDBCをラップしたライブラリ。
本来はJdbcTemplateにDB接続情報となるDataSourceを渡してインスタンスを作成するが今回の入門ガイドではSpringBootのオートコンフィグレーションという機能でH2という組み込みDBを使用する設定で自動設定されている。組み込みDBについて通常は単体テストとかで使われるらしい。
JdbcTemplateも使いこなせたらよさそうだけど、Mybatisを使ってみたいので今はあまり深追いはしない。
使い方のサンプルは以下で確認できる。

https://spring.pleiades.io/spring-framework/reference/data-access/jdbc/core.html#jdbc-JdbcTemplate

### H2
単体テストで使ったりするらしい。これはMybatisと組み合わせて使うことがありそうなのでもう少ししたら深堀をやりそう。
>org.springframework.jdbc.datasource.embedded パッケージは、組み込み Java データベースエンジンのサポートを提供します。HSQL (英語)  、H2 (英語)  、Derby [Apache] (英語)   のサポートはネイティブで提供されます。拡張可能な API を使用して、新しい組み込みデータベース型と DataSource 実装をプラグインすることもできます。

https://spring.pleiades.io/spring-framework/reference/data-access/jdbc/embedded-database-support.html


# eclipseで実行してみる。
今回も前回に引き続きサーバーとしての機能は必要ないのでWebApplicationType.NONEに設定する。
```java
	public static void main(String[] args) {
		//SpringApplication.run(SpringBootGuide04Application.class, args);
		SpringApplication app = new SpringApplication(SpringBootGuide04Application.class);
		app.setWebApplicationType(WebApplicationType.NONE);
		app.run(args);
	}
```
前回はCommandLineRunner型のインスタンスを作ってBeanとしてDIコンテナに登録して起動の最後に実行していたけど、今回はCommandLineRunnerを実装していくパターンだった。実行したい処理が一つだけならこれでもよさそう。
インターフェースを実装するときは`@Override`をつけるそうな。
```java
@SpringBootApplication
public class SpringBootGuide04Application implements CommandLineRunner{
        :
        :
	@Override
	public void run(String... args) {
            :
            :
```
実行すると以下のような出力が表示される。
```

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
[32m :: Spring Boot :: [39m              [2m (v3.2.4)[0;39m

[2m2024-04-19T14:22:43.624+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36mc.e.r.SpringBootGuide04Application      [0;39m [2m:[0;39m Starting SpringBootGuide04Application using Java 17.0.6 with PID 11984 (D:\Spring学習\workspace-sub\SpringBootGuide04\bin\main started by socce in D:\Spring学習\workspace-sub\SpringBootGuide04)
[2m2024-04-19T14:22:43.627+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36mc.e.r.SpringBootGuide04Application      [0;39m [2m:[0;39m No active profile set, falling back to 1 default profile: "default"
[2m2024-04-19T14:22:44.420+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36mc.e.r.SpringBootGuide04Application      [0;39m [2m:[0;39m Started SpringBootGuide04Application in 1.333 seconds (process running for 3.399)
[2m2024-04-19T14:22:44.425+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m SQLを実施します。
[2m2024-04-19T14:22:44.425+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m テーブルが存在する場合はDROPします。
[2m2024-04-19T14:22:44.429+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36mcom.zaxxer.hikari.HikariDataSource      [0;39m [2m:[0;39m HikariPool-1 - Starting...
[2m2024-04-19T14:22:44.673+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36mcom.zaxxer.hikari.pool.HikariPool       [0;39m [2m:[0;39m HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:b23062e0-f1ce-4ab5-bd97-ab024d7972c9 user=SA
[2m2024-04-19T14:22:44.675+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36mcom.zaxxer.hikari.HikariDataSource      [0;39m [2m:[0;39m HikariPool-1 - Start completed.
[2m2024-04-19T14:22:44.688+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m テーブルを作成します。
[2m2024-04-19T14:22:44.695+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m 姓：遠藤　名：さくら
[2m2024-04-19T14:22:44.695+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m 姓：賀喜　名：遥香
[2m2024-04-19T14:22:44.695+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m 姓：齋藤　名：飛鳥
[2m2024-04-19T14:22:44.696+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m INSERTを開始します。
[2m2024-04-19T14:22:44.713+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m INSERTを完了しました。
[2m2024-04-19T14:22:44.713+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m IDが1,2のデータを取得します。
[2m2024-04-19T14:22:44.728+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m Customer[id=1, firstName='遠藤', lastName='さくら']
[2m2024-04-19T14:22:44.729+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [           main][0;39m [2m[0;39m[36m                                        [0;39m [2m:[0;39m Customer[id=2, firstName='賀喜', lastName='遥香']
[2m2024-04-19T14:22:44.734+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [ionShutdownHook][0;39m [2m[0;39m[36mcom.zaxxer.hikari.HikariDataSource      [0;39m [2m:[0;39m HikariPool-1 - Shutdown initiated...
[2m2024-04-19T14:22:44.737+09:00[0;39m [32m INFO[0;39m [35m11984[0;39m [2m---[0;39m [2m[SpringBootGuide04] [ionShutdownHook][0;39m [2m[0;39m[36mcom.zaxxer.hikari.HikariDataSource      [0;39m [2m:[0;39m HikariPool-1 - Shutdown completed.
```

# 感想
ポケカにはまってしまって時間が空いてしまった。そして何より今回は内容が濃かったので最低限腹落ちさせるまでに時間が必要だった。
DB周りの技術をやってみたいっていうのもあるので派生してやっていった方がいいなと思う内容がいくつか出てきたので以下は近いうちにやろうと思う。
・Mybatis
・インメモリDB
・DataSource
・HikariCP
・StreamAPI
JDBCでのDBとのやり取り以外にORマッパーでのやり取りがあって、MybatisとかいうORマッパーをめちゃくちゃよく聞くからMyBatisを使ったポートフォリオなんて作ってみたら行きたい案件に行ける可能性が高くなるかもしれない。