JDBC勉強備忘録（Update処理）

## 備忘録目的
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
その他：本文に追記

## 本文
まずはUpdate処理をしているファイルを確認する。
（以下、Update処理をしているファイルと考えられるファイルのコード）
```Java:/Sample_4/src/j4_02/Sample4_02_1_Upd_Main.java
package j4_02;

/**----------------------------------------------------------------------*
 *■■■Sample4_02_1_Ins_Mainクラス■■■
 *概要：メイン（ユーザーの登録）
 *----------------------------------------------------------------------**/
public class Sample4_02_1_Ins_Main {
	public static void main (String[] args) {

		//コマンドラインから登録するユーザーの情報を受け取りDTOに格納
		Sample4_02_1_Common_DTO subscribeDto = new Sample4_02_1_Common_DTO();
		subscribeDto.setId(     Integer.parseInt(args[0])  );
		subscribeDto.setName(   args[1]                    );
		subscribeDto.setGender( args[2]                    );
		subscribeDto.setAge(    Integer.parseInt(args[3])  );
		subscribeDto.setCourse( args[4]                    );

		//ビジネスロジック（ユーザーの登録）クラスのインスタンス化＆メソッド起動
		Sample4_02_1_Ins_BusinessLogic blDel = new Sample4_02_1_Ins_BusinessLogic();
		blDel.subscribe( subscribeDto );

	}
}
```
```Java:/Sample_4/src/j4_02/Sample4_02_1_Upd_BusinessLogic.java
package j4_02;

/**----------------------------------------------------------------------*
 *■■■Sample4_02_1_Upd_BusinessLogicクラス■■■
 *概要：ビジネスロジック（ユーザーの情報更新）
 *----------------------------------------------------------------------**/
public class Sample4_02_1_Upd_BusinessLogic {

	/**----------------------------------------------------------------------*
	 *■updateメソッド
	 *概要　：対象のユーザー情報を更新する
	 *引数　：対象のユーザーデータ（Sample4_02_1_Common_DTO型）
	 *戻り値：なし
	 *----------------------------------------------------------------------**/
	public void update(Sample4_02_1_Common_DTO targetUserDto) {

		//-------------------------------------------
		//データベースへの接続を実施
		//-------------------------------------------

		//DAOクラスをインスタンス化＆対象のユーザーデータを更新するよう依頼
		Sample4_02_1_Common_DAO dao = new Sample4_02_1_Common_DAO();
		boolean result = dao.updateMemberInfo(targetUserDto);

		//終了メッセージを表示
		if(result){
			System.out.println("[INFO]更新処理が正常終了しました" ) ;
		}else{
			System.out.println("[INFO]更新処理に失敗しました" ) ;
		}

	}
}
```
```Java:/Sample_4/src/j4_02/Sample4_02_1_Common_DAO.java
	/**----------------------------------------------------------------------*
	 *■updateMemberInfoメソッド
	 *概要　：「uzuz_member」テーブルのレコードを1行更新する
	 *引数　：更新データ（Sample4_02_1_Common_DTO型）
	 *戻り値：実行結果（真：成功、偽：例外発生）
	 *----------------------------------------------------------------------**/
	public boolean updateMemberInfo(Sample4_02_1_Common_DTO dto){

		//-------------------------------------------
		//JDBCドライバのロード
		//-------------------------------------------
		try {
			Class.forName(DRIVER_NAME);       //JDBCドライバをロード＆接続先として指定
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}

		//-------------------------------------------
		//SQL発行
		//-------------------------------------------

		//JDBCの接続に使用するオブジェクトを宣言
		//※finallyブロックでも扱うためtryブロック内で宣言してはいけないことに注意
		Connection        con = null ;   // Connection（DB接続情報）格納用変数
		PreparedStatement ps  = null ;   // PreparedStatement（SQL発行用オブジェクト）格納用変数

		//実行結果（真：成功、偽：例外発生）格納用変数
		//※最終的にreturnするため、tryブロック内で宣言してはいけないことに注意
		boolean isSuccess = true ;

		try {

			//-------------------------------------------
			//接続の確立（Connectionオブジェクトの取得）
			//-------------------------------------------
			con = DriverManager.getConnection(JDBC_URL, USER_ID, USER_PASS);

			//-------------------------------------------
			//トランザクションの開始
			//-------------------------------------------
			//オートコミットをオフにする（トランザクション開始）
			con.setAutoCommit(false);

			//-------------------------------------------
			//SQL文の送信 ＆ 結果の取得
			//-------------------------------------------

			//発行するSQL文の生成（UPDATE）
			StringBuffer buf = new StringBuffer();
			buf.append(" UPDATE uzuz_member ");
			buf.append("  SET               ");
			buf.append("   name   = ? ,     ");  //第1パラメータ
			buf.append("   gender = ? ,     ");  //第2パラメータ
			buf.append("   age    = ? ,     ");  //第3パラメータ
			buf.append("   course = ?       ");  //第4パラメータ
			buf.append("  WHERE             ");
			buf.append("   id     = ?       ");  //第5パラメータ

			//PreparedStatementオブジェクトを生成＆発行するSQLをセット
			ps = con.prepareStatement(buf.toString());

			//パラメータをセット
			ps.setString( 1, dto.getName()   );  //第1パラメータ：更新データ（名前）
			ps.setString( 2, dto.getGender() );  //第2パラメータ：更新データ（性別）
			ps.setInt(    3, dto.getAge()    );  //第3パラメータ：更新データ（年齢）
			ps.setString( 4, dto.getCourse() );  //第4パラメータ：更新データ（コース）
			ps.setInt(    5, dto.getId()     );  //第5パラメータ：更新データ（ID）

			//SQL文の送信＆戻り値として更新件数を取得
			int updCount = ps.executeUpdate();

			//SQL実行結果を表示
			System.out.println("[INFO]" + updCount + "行更新しました") ;

		} catch (SQLException e) {
			e.printStackTrace();

			//実行結果を例外発生として更新
			isSuccess = false ;

		} finally {
			//-------------------------------------------
			//トランザクションの終了
			//-------------------------------------------
			if(isSuccess){
				//明示的にコミットを実施
				try {
					con.commit();
				} catch (SQLException e) {
					e.printStackTrace();
				}

			}else{
				//明示的にロールバックを実施
				try {
					con.rollback();
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}

			//-------------------------------------------
			//接続の解除
			//-------------------------------------------

			//PreparedStatementオブジェクトの接続解除
			if (ps != null) {    //接続が確認できている場合のみ実施
				try {
					ps.close();  //接続の解除
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}

			//Connectionオブジェクトの接続解除
			if (con != null) {    //接続が確認できている場合のみ実施
				try {
					con.close();  //接続の解除
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}

		}

		//実行結果を戻す
		return isSuccess ;

	}
```
Upd_MainとDAOのUpdateメソッドの内容から、Insertと同じように配列を記載する必要があると仮定。
しかし、Update処理をしたい場合には、一部のみをUpdateしたい場合が多いと考えられるため、
一部のみUpdateできるのかを確認する。
引数には次のように値を設定する。「100 M」（id = 100, gender = F→M）
結果、以下の表示がコンソールにされた。
```
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 2 out of bounds for length 2
	at j4_02.Sample4_02_1_Upd_Main.main(Sample4_02_1_Upd_Main.java:14)
```
エラー内容を確認するため、「Index 2 out of bounds for length 2」で検索し、[このサイト](https://programmer-life.work/java/indexoutofboundsexception)を参考にした。
予想通り、引数の数が足りない（配列との整合性が合わない）というエラーだった。

次に、配列に合うように引数を設定した「100 ogawa M 80 DX」（id = 100を検索し、nameを変えず、他を変えている）
結果、
```
[INFO]1行更新しました
[INFO]更新処理が正常終了しました
```
terminalでも確認。
```
mysql> select * from UZUZ_MEMBER where id = 100;
+-----+-------+--------+-----+--------+
| ID  | NAME  | GENDER | AGE | COURSE |
+-----+-------+--------+-----+--------+
| 100 | ogawa | M      |  80 | DX     |
+-----+-------+--------+-----+--------+
1 row in set (0.00 sec)
```
変更されていた。

正常な動作は確認できたが、以下のことが気になっている。
・部分的に引数を設定し、変更できるようにしたい。
・タイムスタンプ機能を付与したい。
・そもそも、argsではなくprintにすることもできるのでは？

とりあえず、残りのdelete処理が正常に動作するのかを確認後、他の処理と合わせて、改良をしたいと判断する。

次回、**JDBC勉強備忘録（Delete処理）**