【データベース•学習ログ2】Javaからデータベースに接続し、テーブルを作成する

<font color=gray>使用教材：侍テラコヤ『Javaとデータベースの連携方法を学ぼう』https://terakoya.sejuku.net/programs/129/chapters</font>

## JavaからMySQLに接続する
《準備》
(1)MySQL Workbenchを導入
(2)データベースを作成
(3)eclipseでプロジェクトを立ち上げ、SQLを書き込むファイルを用意する

#### 1.JDBCよりクラスをインポート
```java
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
```
* Connection … データベースとの接続を管理するクラス
* DriverManager … JDBCを取り扱うためのクラス
* SQLException … データベースの取り扱いで発生した例外を処理するクラス

#### 2.JDBCを用いてデータベースに接続
```java
		try {
			// データベース接続
			Connection con = DriverManager.getConnection(
				"jdbc:mysql://localhost/java_db",
				"root",
				"【パスワード】"
			);
			
			System.out.println("データベース接続成功");
			System.out.println(con);
			
			//データベース接続解除
			con.close();
			
		} catch(SQLException e) {
			System.out.println("データベース接続失敗：" + e.getMessage());
		}
```
tryブロックで接続を試行し、catchブロックで例外時の処理を行う。
接続が成功すると、接続情報を格納したDriverManagerクラスのgetConnection()メソッドを返す。
（getConnectionには[URL],[ユーザー名],[パスワード]を返す）
【実行後の画面】
![スクリーンショット 2024-01-04 125319.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/8e817d8f-c241-dfef-cb82-d5482e6ea268.png)

## Javaからテーブルを作成する
データベース操作の種類には**更新系**と**取得系**があり、SQLクエリの実行方法は異なる。

### ★更新系の実行方法★

##### 1.SQLクエリの準備
実行したいSQLクエリの中身を確定し、DBMSに送信できる状態に整える。
中身が固定の場合は、ConnectionクラスのcreateStatement()メソッド、可変の場合はprepareStatement()メソッドを使う。
```java
//【固定の場合】
Statement statement = con.createStatement();
String sql = "SELECT name FROM users";
//【可変の場合】
String sql = "SELECT name From users WHERE id=?"
preparedStatement statement = con.prepareStatement(sql);
statement.setInt(1,id)
```
##### 2.SQLクエリの実行
準備したSQLクエリを実行するときは、StatementクラスのexecuteUpdate()メソッドを使う。
```java
int rowCnt = statement.executeUpdate(sql);
```
##### 3.実行後の片付け
不要なデータ領域を残さないために、実行したstatementをclose()メソッドで片付ける。
```java
statement.close();
con.close();
```
##### 4.テーブル作成
データベース内にテーブルを作成するときは、CREATE TABLE文を使う。
```sql
CREATE TABLE テーブル名(カラム名 データ型[オプション],…)
```
|データ型|説明|データ例|
|-|-|-|
|INT|整数を扱える型|123、0、-30|
|FLOAT|浮動小数点数を扱える型|0.123|
|BOOLEAN|真偽値を扱う型|TRUE、FALSE|
|VARCHAR|最初に決めた文字数までの文字列を扱える型|こんにちは|
|DATE|年月日を含む日付を扱える型|2023-1-23|

データ項目にルールを加えたい場合は、データ型の後ろに下記のオプションを追記する。
|オプション|説明|
|-|-|
|NOT NULL|データが何もない状態を禁止する|
|PRIMARY KEY|カラムを主キーに設定する。テーブル内のレコードを一意に識別するためのカラムのこと。値の重複が有り得ないカラムに設定する|
|AUTO_INCREMENT|自動的に番号を1ずつ増やし、重複しないデータを設定する。|

```java
package text.section_04;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class Dbtable_1 {
	public static void main(String[] args) {
		Connection con = null;
		Statement statement = null;
		
		try {
			// データベースに接続
			con = DriverManager.getConnection(
				"jdbc:mysql://localhost/java_db",
				"root",
				"【パスワード】"
			);
		
			System.out.println("データベース接続成功");
			
			// SQLクエリを準備
			statement = con.createStatement();
			String sql = """
						CREATE TABLE users (
							id INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY.
							name VARCHAR(60) NOT NULL,
							age INT(11)
						);
						""";
			
			// SQLクエリを実行（DBMSに送信)
			int rowCnt = statement.executeUpdate(sql);
			System.out.println("テーブルを作成:rowCnt=" + rowCnt );
		} catch(SQLException e) {
			System.out.println("エラー発生：" + e.getMessage());
		} finally {
			// 使用したオブジェクトを解放
			if( statement != null ) {
				try { statement.close(); } catch(SQLException ignore) {}
			}
			if( con != null ) {
				try { con.close(); } catch(SQLException ignore) {}
			}
			
		}
	}

}
```
《ポイント》
* SQLクエリが長くなる時は、テキスト・ブロック機能を活用する。（"""で囲む）
* finallyブロックは例外が発生しなくても必ず実行される処理。処理に失敗してもオブジェクトを正しく解放できるようにfinallyブロックでclose()メソッドを実行する。closeが失敗した場合に有効な対処方法はなく、この場合は**ignore**を用いることで、例外だけキャッチして終了できる。

【実行結果】
![スクリーンショット 2024-01-04 160829.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/9680302b-5177-cca0-99db-174fa250470e.png)
MySQL Workbenchから確認すると、「users」というテーブルが作成されている。
![スクリーンショット 2024-01-04 161021.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3520365/f040e039-0c17-66d0-dfcf-db761b264477.png)

<hr>