JDBCの学習備忘録（select構文）

## 備忘録目的
DAOに関しての自分が認識していることの確認と躓いたところや調査方法、仮定したことなど、過程を記録する。
（技術的なことはサイトのリンクを貼る）

## 環境
OS：macOS 12.5.1
IDE:Eclipse IDE for Enterprise Java Developers.
　　Version: 2019-12 (4.14.0)
　　Build id: 20191212-1212
DB：Ver 8.0.32 for macos12.6 on x86_64 (Homebrew)
クラスパス:mysql-connector-j-8.0.32.jar
その他：本文に追記

# 本文
## サンプルソースコードの設置
サンプルソースコードを設置しようと、zipから展開後に「サンプルソースコード」ディレクトリ直下のSample4_02_2をドラッグ＆ドロップをしてエラーになる。
エラー内容は見ていないが、ファイルの内容からパッケージが違うことを確認し、パッケージを作成後、再度設置。
それでも、エラー表示。
そもそも、ディレクトリ構造を確認していないというPONを発揮していたことが原因。
ディレクトリ構造を確認後、javaファイルのみを作成したパッケージにドラッグ＆ドロップし、解決。

##　Main.javaファイルの実行
設置したサンプルコードを実行したところ、
```java:Sample4_02_1_Del_Main.java
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 0 out of bounds for length 0
	at j4_02.Sample4_02_1_Del_Main.main(Sample4_02_1_Del_Main.java:11)
```
上記のエラーコードが表示された。
`Exception in thread`であることから例外ということは判明し、`ArrayIndexOutOfBoundsException`を検索した内容から、配列の数が合っていないことが原因とわかる。
このことから、Del_Mainの処理（Del_Main.javaはDBのデータを削除する際に使用するjavaファイル）がデータベースの状況と合っていないことが問題であると仮定。
同ファイルを確認したところ、下記のコマンドを確認。
```java:Sample4_02_1_Del_Main.java
int unsubscribeId = Integer.parseInt(args[0]);
```
`Integer.parseInt`を検索し、[このサイト](https://www.fenet.jp/java/column/java_tips/6643/)の内容から、引数が0ならデータベースの状況と合っていないことによるエラーにはならないのではと考える。
そもそも、引数に0しか渡さない仕様なのだろうか？
そんな仕様はこのファイルに合っているのだろうか？　ということから、
argsのことを全く知っていないことで、0を引数にしていると思い込んでいると考え、
「Java args」で検索し、[このサイト](https://www.fenet.jp/java/column/java_tips/6643/)の内容から実行方法が違っていたと仮定。
ただ、実行をすると確認はできるが、データが削除されるため、一旦保留してテーブルの内容を一覧化して表示するファイルを実行することにする。
（そもそも、実行するファイルが考えなさすぎだろ...と今になって思う💦）

## テーブルの内容を一覧化して表示するファイルを実行
ファイルを変更し、再度「アプリケーションで実行」を行う。
上記の方法を行ったのは、実行方法が違う可能性を高めるため（ぶっちゃけ、検索ならコマンドラインの入力なしでもやれるんじゃないかと、`args[0]`があるのにやってしまった）

「実行の構成」の引数に必要な値を知るため、以下のコマンドから順に引数を参照するためのコマンドを確認する。
```Java:Sample4_02_1_Sel_Main.java
Sample4_02_1_Sel_BusinessLogic blSel = new Sample4_02_1_Sel_BusinessLogic();
blSel.extract( extractionId );
```
```Java:Sample4_02_1_Sel_BusinessLogic.java
Sample4_02_1_Common_DAO dao = new Sample4_02_1_Common_DAO();
Sample4_02_1_Common_DTO extractedDto = dao.selectMemberInfo(targetUserId);
```
```java:/Sample_4/src/j4_02/Sample4_02_1_Common_DAO.java
public Sample4_02_1_Common_DTO selectMemberInfo(int pk){
```

Sample4_02_1_Common_DAO.javaを確認している途中で、そもそもデータベースに接続する内容が違っていることを確認。（以下のコマンド)
```java:/Sample_4/src/j4_02/Sample4_02_1_Common_DAO.java
//-------------------------------------------
	//データベースへの接続情報
	//-------------------------------------------

	//JDBCドライバの相対パス
	//※バージョンによって変わる可能性があります（MySQL5系の場合は「com.mysql.jdbc.Driver」）
	String DRIVER_NAME = "com.mysql.cj.jdbc.Driver";

	//接続先のデータベース
	//※データベース名が「test_db」でない場合は該当の箇所を変更してください
	String JDBC_URL    = "jdbc:mysql://localhost/test_db?characterEncoding=UTF-8&serverTimezone=JST&useSSL=false";

	//接続するユーザー名
	//※ユーザー名が「test_user」でない場合は該当の箇所を変更してください
	String USER_ID     = "test_user";

	//接続するユーザーのパスワード
	//※パスワードが「test_pass」でない場合は該当の箇所を変更してください
	String USER_PASS   = "test_pass";
```
上記の内容を変更後、以降のコマンドを確認していると、下記のコマンドを確認。
```java:/Sample_4/src/j4_02/Sample4_02_1_Common_DAO.java
buf.append("   id = ?      ");  //第1パラメータ
//PreparedStatement（SQL発行用オブジェクト）を生成＆発行するSQLをセット
ps = con.prepareStatement(buf.toString());
//パラメータをセット
ps.setInt(1, pk);
//SQL文の送信＆戻り値としてResultSet（SQL抽出結果）を取得
rs = ps.executeQuery();
```
`buf.append("   id = ?      "); `から引数が必要であると仮定し、`ps.setInt(1, pk);`の処理内容を「setInt」で検索し、[このサイト](https://kanda-it-school-kensyu.com/java-jdbc-contents/jj_ch03/jj_0302/)で確認後「実行の構成」必要な引数は該当のテーブルに格納されているidの数まで（int型）であると仮定。

「実行の構成」にidの最大値のみを設定し、実行。
結果、実行は成功し、設定したidのレコードのみが表示された。（以下、表示内容）
```java:Sample4_02_1_Sel_Main.java
**************取得結果***************
*ID：5
*名前：CHAMP
*性別(M:男,F:女)：M
*年齢：5
*コース：MARKET
*************************************
```
次に、複数指定ができるかを確認。
引数はselect構文に沿ったものであると考えられるため、「select where 引数」で検索する。
だが、[IBMのサイト](https://www.ibm.com/docs/ja/i/7.3?topic=index-search-syntax)を確認したところ、ワイルドカードで全数検索はできるかもしれないと仮定。
でも、複数のレコードを検索する方法とは違うと考えられるため、配列に関してのエラーが出ると仮定し、全数検索で実行してみる。
結果、以下のような今までとは違ったエラーが表示された。
```java:Sample4_02_1_Sel_Main.java
Exception in thread "main" java.lang.NumberFormatException: For input string: "*"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Integer.parseInt(Integer.java:638)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at j4_02.Sample4_02_1_Sel_Main.main(Sample4_02_1_Sel_Main.java:11)
```
`NumberFormatException: For input string: "*"`文字列で読み込まれたため、型が違うことによるエラーと考えられる。
そもそも、select構文でwhereを使用するなら、同じ型で、複数にするなら`,`で良いことを思い出した。
引数に、`1,2,3,4,5`を入力し、実行。
以下のエラーが表示される。
```java:Sample4_02_1_Sel_Main.java
Exception in thread "main" java.lang.NumberFormatException: For input string: "1,2,3,4,5"
	at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
	at java.base/java.lang.Integer.parseInt(Integer.java:652)
	at java.base/java.lang.Integer.parseInt(Integer.java:770)
	at j4_02.Sample4_02_1_Sel_Main.main(Sample4_02_1_Sel_Main.java:11)
```
引数以外は同じエラー内容になった（こういうところがPONなんだよな〜）
そもそも、仕様上できないようになっているのか？
複数の結果を手軽に出せるようにするにはどうすれば良いのか？
id以外でも検索ができるようにするにはどうすれば良いのか？
テーブルを増やすとどのようなプログラムが必要になるか？

色々、疑問点などはあるが、一旦selectの処理は置いてInsertの構文を確認することにする。

仮定として、DAOはデータベースとの橋渡し役に必要なファイルとし、DTOはテーブル内容の定義と保守をしているとして、他の処理を確認することにする。

次回　**JDBCの学習備忘録（Insert構文)**