JDBCの扱い

# Javaでデータベースを扱う
Javaデータベースを扱うには各データベースベンダーから提供されているJDBCドライバを管理するJDBCドライバマネージャーをJavaプログラム内でimportして使用する。

提供されているJDBCドライバはJavaが規定したJDBC APIインタフェースを実装しているためJDBCドライバマネージャーを用いれば異なるデータベースでも同じ方法でコーディングを行うことが出来るのである。

JDBCはjava.sql.内に存在しているので使用する際には
~~~Importsql.java
import java.sql.* ;
~~~
が必要になる。

JDBCでできることは

:::note
1.データベースに接続(DriverManagerクラスのメソッド)
2.SQL文の作成(Connectionオブジェクトのメソッド)
3.SQL文の実行(PrepareStatementオブジェクトのメソッド)
4.実行した結果得られたDBの操作(ResultSetクラスのメソッド)
5.データベースの接続切断(Connectionオブジェクトのメソッド)
:::
基本的にDBを扱うのだが項目に分けた理由としては()内にも記述した通り各手順で扱うオブジェクトが異なっているためである。

## 1.データベースに接続
まず第一にデータベースに接続することから始まる。
JDBCでデータベースに接続するには``DriverManagerクラス``にある``getConnetion()メソッド``を使用する。
``getConnetion()``は引数に``接続先情報，接続するユーザー名，パスワード`` の3つを入れ，問題がなければデータベースに接続することが出来る。問題があった場合は``SQLException``がthrowされる。

他にも
``getConnection(String url)``
 指定されたデータベースの URL への接続を試みる。

``getConnection(String url, Properties info)``
指定されたデータベースの URL への接続を試みる。
といった接続方法がある。

このメソッドは戻り値の型が``Connection``である．
今後指定しログインしたデータベースに接続してある``Connectionオブジェクト``の上でSQL文を作成するオブジェクトや操作をするオブジェクトを作成する。

## 2.SQL文の作成
SQL文を作成するには``Connectionオブジェクト``で``SQL文を作成できるオブジェクト``をもらう必要がある。
ConnectionメソッドにはSQL文を作成できるオブジェクトを受け取る``prepareStatement(String sql)``メソッドがある。
引数sqlにはパラメータを``?``にしたSQL文を入れる。
    ?を入れる理由として``SQLインジェクション対策``や``where句以下``を指定するため等がある。

https://www.softbanktech.co.jp/special/blog/it-keyword/2021/0020/

?のままではsql文を実行した際SQLExceptionが発生してしまうのでその後の操作で?に値を入れる必要がある。``prepareStatementオブジェクト``の``setXXXメソッド``を用いることで?に値を入れることが出来る。``setXXXメソッド``でsql文を完成させ``prepareStatementオブジェクト``で実行を行う。
``prepareStatement(String sql)``は戻り値が``PreparedStatementオブジェクト``なのでオブジェクトの宣言が必要になる。
~~~Sample.java

String url = "jdbc:mysql://localhost:3306/sampledb";
String userName = "sample";
String password = "mysql";

con = DriverManager.getConnection(url, userName, password);

// SQL文の作成
String sql = "SELECT * FROM sample_table WHERE sample_column = ?";
stmt = con.prepareStatement(sql);
stmt.setInt(1,20);

~~~

## 3.SQL文の実行
完成したsql文を実行を行うには，``PreparedStatementオブジェクト``の``executeQuery()``か``executeUpdate()``を使用する。executeQuery()メソッドは戻り値に``ResultSetオブジェクト``が返却され、executeUpdate()メソッドは戻り値に``int型``が返却される。``executeQuery()``ではResultSetにデータベースが返却されているイメージである。
データがなかった場合でもcolumnの行は返却されている。

~~~Sample.java
// SQL文の作成
String sql = "SELECT * FROM sample_table WHERE sample_column = ?";
stmt = con.prepareStatement(sql);
stmt.setInt(1,20);

//SQL文の実行
ResultSet res = null;
res = stmt.executeQuery();
~~~


イメージとしてデータがあった場合は

| column1 | column2 | column3 |
|:-:|:-:|:-:|
|  ~~~ | ~~~  |  ~~~ |

データがない場合では
| column1 | column2 | column3 |
|:-:|:-:|:-:|

といったデータが返却されている。

## 4.実行した結果得られたDBの操作
このような図が返却され最初はcolumnの行を選択している。そのためデータを取得するには次の行を選択する必要がある。次の行に移るには``next()メソッド``を使用する。返却される値はboolean型のため次の行(データ)がある場合はtrue，(データが)無い場合はfalseが返却される。
``next()メソッド``trueの場合ではresインスタンス次の行に移行し、データの行を扱っている。データの行を扱っている場合ResultSetオブジェクトの``getXXX("DBのcolumn")``を呼び出すことが出来る。引数にはDBのcolumn名を入れることで必要な値を得ることが出来る。XXX部分には``String``や``int``といった型を指定できる。

## 5.データベースの接続切断
最後にDBの接続を切断する場合、DBを扱うオブジェクトすべてをDBから切断する必要がある。切断する順番は作成した最後から順に切断を行う。
実際にPreparedStatementとResultSetはデータベースへのアクセスを行うクラスを作り、そのクラスを通してデータベースへアクセスするDAOと呼ばれるクラスで作成しそのクラス内でcloseをする必要がある。
~~~Sample.java
// データベースの接続切断
// 結果セットのクローズ
if (res != null) {
	res.close();
}
// ステートメントのクローズ
if (stmt != null) {
	stmt.close();
}
// 接続のクローズ
if (con != null) {
	con.close();
}
~~~

JDBCの扱いは異常である。
最後にサンプルプログラムを載せる。

## サンプルプログラム
~~~Sample.java
package sample;

import java.sql.*;


public class Samples {
	public static void main(String args[]) {
		Connection con = null;
		PreparedStatement stmt = null;
		ResultSet res = null;

		String url = "jdbc:mysql://localhost:3306/sampledb";
		String userName = "sample";
		String password = "mysql";

		try {
			// データベースに接続
			con = DriverManager.getConnection(url, userName, password);

			// SQL文の作成
			String sql = "SELECT employee_id, employee_name, department_id, phone "
						+ "FROM employee WHERE department_id = ?";
			stmt = con.prepareStatement(sql);
			stmt.setInt(1,20);

			// SQL文の実行
			res = stmt.executeQuery();

			System.out.println("Result------------------------");

			// 結果セットから情報を取り出す
			while (res.next()) {
				System.out.print(res.getInt("employee_id") + ",");
				System.out.print(res.getString("employee_name") + ",");
				System.out.print(res.getInt("department_id") + ",");
				System.out.print(res.getString("phone"));
				System.out.println();
			}
			System.out.println("-------------------------------End");
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				// 結果セットのクローズ
				if (res != null) {
					res.close();
				}
				// ステートメントのクローズ
				if (stmt != null) {
					stmt.close();
				}
				// 接続のクローズ
				if (con != null) {
					con.close();
				}
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}
~~~