Java JDBC

# はじめに
JavaのWebアプリケーションに，DBを利用した機能を実装するために必要となる**JDBC**についてまとめる．まずは，JDBCの概要をまとめてから，基本的な実装方法についてまとめる．

# JDBCとは
JDBCは"<font color="red">J</font>ava <font color="red">D</font>ata<font color="red">B</font>ase <font color="red">C</font>onnectivity"の頭文字をとったもので，Javaプログラムがデータベース管理システムにアクセスできるようにするものである．

JDBCを構成する基本要素は以下の二つである．
**1．　JDBC API**
Javaアプリケーションがデータベースにアクセスするためのクラス/インタフェースの集まりである．これらを用いて，データベースを操作するプログラムを作成する．
**2． JDBCドライバマネージャー**
複数のJDBCドライバを管理するためのクラスで，目的のデータベースに対応したJDBCドライバを選択し接続するために使用する．
**3． JDBCドライバ**
特定のデータベースシステムとの通信を可能にするJavaクラスの集合で，使用したいデータベースの種類(Oracle・MySQL・PostgreSQLなど)ごとに用意する必要がある．

JDBC APIとドライバマネジャーはJDKにすでに含まれているため，Javaアプリの開発環境が整っていれば準備できているはず．JDBCドライバは，データベースベンダーーが提供してくれるもので，Webサイトからダウンロードすることで用意する．

## メリット
JDBCの大きなメリットは，__使用するDBが異なっても，Javaのプログラムをほぼ変えなくてもいい__ という点である．
JDBCドライバはDBの操作を行うJavaプログラムを特定のデータベースシステム用に変換してくれる．そのため，使用するDBを変更する場合は，開発者はJDBC APIに沿った書き方さえ行えば，使用するDBごとのJDBCドライバを用意するだけで済む．

## JDBCのイメージ
![JDBC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3133563/16fee6ee-7c7b-e4fd-5fe0-29a35d6c0e78.png)

# JDBCの実装方法
JDK(JDBC API)やJDBCドライバ，使用するDBのインストールなどの環境構築が終わっていることを前提に，実際にJavaプログラムからデータベースの操作を行うまでの流れをまとめる．ここでは例としてデータベースはMySQLを使うが，他のデータベースでもほぼ変わらない．

## 使用するクラス&インタフェース
__Driver Managerクラス__
→データベースへ接続するJDBCドライバの管理を行うために使用する
__Connectionインタフェース__
→データベースとの通信やトランザクション管理など，データベースへのアクセスのための基本的なメソッドを提供する
__Statementインタフェース__
→SQLクエリをデータベースに送信するために使用する．
__ResultSetインタフェース__
→データベースから取得した行と列を結果として保持する．アプリケーションではこれを使用してデータを取り出す．
__SQLExceptionクラス__
→データベースアクセス時に発生する時の例外処理を行うために使用する．

# Javaプログラムで記述するJDBCの処理の流れ
MySQLを利用した時の例
```java
//データベースの接続
Class.forName("com.mysql.jdbc.Driver");
Connection connection =　DriverManager.getConnection("url","username","password");
//データ操作の準備
String Query = "SQL文";
PreparedStatement statement = connection.prepareStatement(Query);
//データベースの操作
ResultSet resultSet = statement.executeQuery();
resultSet.getInt("id");
//リソースの解放
resultSet.close();
Statement.close();
connection.close();
```
JDBCの処理の流れは大きく分けると以下のようになる．
１．データベースへの接続
２．データ操作の準備
３．データの操作(追加・変更・削除)
４．リソースの解放

これらについてもう少し詳しくまとめる．

# データベースへの接続
１．**JDBCのインポート**
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement; //または　java.sql.PreparedStatement;
import java.sql.SQLException;
```
データベースとの接続・操作を行うために必要な上記の4つをインポートする．
Statementに関するインタフェースは，データベースの操作の実装によってインポートするものは変わる．

２．**JDBCドライバのロード**
```java
Class.forName("com.mysql.jdbc.Driver");
```
`Class.forName()`メソッドを利用して，データベースに対応するJDBCドライバを指定する．
MySQLの場合は，`com.mysql.jdbc.Driver`を指定する．

３．**Connectionオブジェクトの取得**
```java
Connection connection =　DriverManager.getConnection("url","username","password");
```
`DriverManager()`メソッドを利用して，Connectionオブジェクトを取得する．引数とは以下の３つを指定する．
* URL：データベースの場所を示すJDBCのURL
* ユーザ名：DB接続のユーザー名
* パスワード：DB接続する際のパスワード

# データ操作の準備
データ操作の準備として，<font color="Tomato">Statement</font>オブジェクトまたは<font color="DodgerBlue">PreparedStatement</font>オブジェクトの取得を行う．
実行するSQL文が静的・動的かによって使い分ける．
```java
//静的　→　Statement
Statement statement = connection.createStatement();

//動的 → PreparedStatement
String sql = "INSERT INTO my_table (column1, column2) VALUES (?, ?)";
PreparedStatement pstmt = connection.prepareStatement(sql);
```
<font color="DodgerBlue">PreparedStatement</font>はあらかじめSQLクエリを用意しておき，SQLクエリ内のパラメータ(SQL文の`?`)に何を入れるかを後で指定する．このように動的なSQLクエリを利用する場合は，<font color="DodgerBlue">PreparedStatement</font>の方が適している．
また，外部データを直接組み込む<font color="Tomato">Statement</font>と比較すると，外部データをパラメータとして扱う<font color="DodgerBlue">PreparedStatement</font>の方がセキュリティの観点から優れている．

# データの操作
データの操作は基本的に"データの検索(参照)"と"データの更新(追加/更新/削除)"の２つを行う．
データ操作の準備で<font color="Tomato">Statement</font>か<font color="DodgerBlue">PreparedStatement</font>を利用するかで方法が異なる．

## <font color="Tomato">Statement</font> オブジェクトの場合

### データの検索(参照)手順
__１．SQLクエリの文字列を用意__
```java
String sql = "SELECT * FROM テーブル名";
```
検索にはSQL文のSELECTを利用して，何を検索するのかを指定する．(SQLの書き方には触れない．)

__２．SQLクエリの実行__
```java
ResultSet result = statement.executeQuery(sql);
```
<font color="Tomato">Statement</font>オブジェクトの`executeQuery`メソッドを利用して，クエリを実行する．引数にはSQLクエリの文字列を渡す．
結果として`ResultSet`オブジェクトが返される．

__３．データベースからの結果を取得__
```java
while(resultSet.next()) {
    //例
    int id = resultSet.getInt("id");
    String name = resultSet.getString("name");
    print(id+":"+name);
}
```
結果として受け取った`ResultSet`オブジェクトを`next()`メソッドを利用することで，取得したデータを１行ずつ取り出すことができる．

### データの更新手順
__1.SQLクエリの文字列を用意__
```java
String sql = "INSERT INTO テーブル名 (データラベル１, データラベル2) values (値1,値2)";
```
データの更新操作は挿入(INSERT)と更新(UPDATE)と削除(DELETE)の３つである．

__２．SQLクエリの実行__
```java
statement.executeUpdate(sql);
```
<font color="Tomato">Statement</font>オブジェクトの`executeUpdate`メソッドを利用する．引数には先ほど定義したSQLクエリの文字列を渡す．メソッドの返り値は実行されたクエリによって変更された行の数である．

## <font color="DodgerBlue">PreparedStatement</font> オブジェクトの場合
### データの検索(参照)手順
__１．SQLクエリ文字列を用意__
```java
String sql = "SELECT * FROM テーブル名 WHERE name = ?";
```
<font color="DodgerBlue">PreparedStatement</font>の場合は，プレースホルダー`?`を使用してクエリを準備する．

__2.PreparedStatementオブジェクトの取得__
```java
PreparedStatement statement = connection.prepareStatement(query);
```
<font color="Tomato">Statement</font>と違い，<font color="DodgerBlue">PreparedStatement</font>オブジェクトの取得はクエリを用意してから行う．`connection.prepareStatement`メソッドの引数にクエリを渡し，<font color="DodgerBlue">PreparedStatement</font>オブジェクトを取得する．

__３．プレースホルダーの値を指定__
```java
statement.setString(1,"data");
```
取得した<font color="DodgerBlue">PreparedStatement</font>オブジェクトの`setString`メソッドを利用して，クエリのプレースホルダーに値を指定する．第一引数となる番号は複数のプレースホルダーを利用した場合に，番号と位置を一致したものを指定する．

4.クエリの実行
```java
ResultSet resultSet = statement.executeQuery();
```
`statement．Query()`メソッドでクエリを実行する．クエリはすでに<font color="DodgerBlue">PreparedStatement</font>オブジェクトに指定されているため，引数は必要ない．
resultSetからのデータの取得は，<font color="Tomato">Statement</font>の場合と同じである．

### データの更新手順
__１．SQLクエリ文字列を用意__
```java
String sql = "INSERT INTO テーブル名 (データラベル１, データラベル2) values (?,?)";
```
検索処理と同様に，<font color="DodgerBlue">PreparedStatement</font>の場合は，プレースホルダー`?`を使用してクエリを準備する．

__2.PreparedStatementオブジェクトの取得__
```java
PreparedStatement statement = connection.prepareStatement(sql);
```
こちらも同様で，<font color="DodgerBlue">PreparedStatement</font>オブジェクトの取得はクエリを用意してから行う．

__３．プレースホルダーの値を指定__
```java
statement.setString(1,"data");
```
これも同様に，プレースホルダーに入れる値を`setString`メソッドで指定する．更新処理の場合は，実際にデータベースに入れる値が指定されることになる．

４．クエリの実行
```java
ResultSet resultSet = statement.executeUpdate();
```
`statement.Update()`メソッドでクエリを実行する．クエリはすでに<font color="DodgerBlue">PreparedStatement</font>オブジェクトに指定されているため，引数は必要ない.

# リソースの解放
```java
resultSet.close();
statement.close();
connection.close();
```
データベースの操作を終えた後は，データベースの接続を明示的に切断する必要がある．`close()`メソッドを利用してデータ操作を行うために取得した`ResultSet`オブジェクトと`Connection`オブジェクト，`Statment`オブジェクトを解放することで，データベースの接続を切断する．

# まとめ
この記事では，JDBCの概要と基本的な実装方法についてまとめた．
JDBCだけでなく，データベースが使えるようになると，Web開発の幅が広がるため，使いこなせるようになりたい．