Java データベース トランザクション(INSERT編)
今回はデータベースのトランザクション処理を実行してみました。
0. 注意事項
- MySQLのポート番号は
3306
がデフォルトになっています。別途設定している場合は定数MYSQLPORT
を変更してください。 - MySQLサーバはデフォルトでオートコミット機能がオンになっています。その為、トランザクション処理を行う場合はオートコミット機能をオフにする必要がありますが、トランザクション処理が終了したらオートコミット機能はオンに戻すようにしましょう。
1. クラスインポート
JavaでMySQLに接続する為に、以下のクラスをインポートします。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
2. 定数宣言
データベース接続の為のConnectionオブジェクトを生成する際に必要なパラメータを宣言します。DATABASE_NAME
にはデータベース名を、USER
とPASS
には、データベースに登録したユーザ名とパスワードを設定します。HOST
は、環境によってアドレス指定を行なってください。
String DATABASE_NAME = "データベース名";
String PROPATIES = "?charcterEncoding=utf-8";
String MYSQLPORT = "3306";
String HOST = "localhost"
String URL = "jdbc:mysql://" + HOST + ":" + MYSQLPORT + "/" + DATABASE_NAME + PROPATIES;
String USER = "ユーザ名";
String PASS = "パスワード";
3. データベース接続用オブジェクトについて
1. Connectionオブジェクト
Connectionオブジェクトは、データベースの接続そのものに必要なオブジェクトです。変数宣言時の初期値はnullで用意しておき、接続時にConnectionオブジェクトを代入します。再度nullを代入することで、接続を終了することができます。
// Connection型変数用意
Connection con = null;
2. PreparedStatementオブジェクト
PreparedStatementオブジェクトは、SQL文の生成・実行を行う為のオブジェクトです。変数宣言時はConnectionオブジェクトと同じく初期値はnullで用意し、データベースに送信するための準備開始時にPreparedStatementオブジェクトを代入します。こちらも再度nullを代入することで、JDBCのリソースを解放することができます。
// PreparedStatement型変数用意
PreparedStatement prst = null;
4. トランザクション
ここからはtry~catch~finally
を使用します。
try
ブロック
try
JDBCDriverクラスにMySQLを指定します。
Class.forName("com.mysql.cj.jdbc.Driver");
データベース接続の為のConnectionオブジェクトを生成します。
con = DriverManager.getConnection(URL, USER, PASS);
トランザクション処理の為、オートコミット機能をオフにします。connection
オブジェクトのsetAutoCommit
メソッドの引数にfalse
を設定するとオートコミット機能がオフになり、true
を設定するとオンになります。
con.setAutoCommit(false);
SQLの生成を行います。
String tableName = "テーブル名";
String sql = "INSERT INTO " + tableName + " (id, name) VALUE (?, ?);";
データベースにSQL文を送信する為、connection
オブジェクトのprepareStatement
メソッドの引数にSQL文を渡すことで、PreparedStatementオブジェクトを生成します。
prst = con.prepareStatement(sql);
PreparedStatement
オブジェクトのsetInt
やsetString
メソッドで、第一引数にプレースホルダの位置を渡し、第二引数に値を渡すことで、SQL文の"?"(プレースホルダ)にパラメータを設定します。
prst.setInt(1, 5);
prst.setString(2, "vellfire");
トランザクションをバッチ処理に登録後、SQLを実行しコミットを行います。
prst.addBatch();
prst.executeBatch();
con.commit();
catch
ブロック
catchブロックではClassNotFoundException
とSQLException
を検査例外として捉えます。ClassNotFoundException
はtry
ブロックので行ったClass.forName
メソッドでドライバの読み込みを行った時に、クラスパスの設定を適切に行っていないと発生する例外です。
catch (ClassNotFoundException | SQLException e)
例外はException
型のe
パラメータのprintStackTrace
メソッドでコンソールに出力することができます。
e.printStackTrace();
このcatch
ブロック内で更にtry~catch
を使用します。その中でロールバック処理を記述します。以下のcatch
ブロックは、ClassNotFoundException
の例外の際に、ロールバック処理に失敗する為、そこで発生したSQLException
の例外をcatch
しています。
try {
con.rollback();
} catch (SQLException e1) {
System.out.println("一階層上のcatchブロックでSQLException以外の例外が発生");
}
finally
ブロック
finally
ブロックでは、データベースの切断処理とオートコミットをオンに戻す処理を記述しています。
finally{
try {
if (null != prst) {
// JDBCのリソースを解放する
prst.close();
}
if (null != con) {
// オートコミットをオンに戻す
con.setAutoCommit(true);
// データベース接続を閉じる
con.close();
}
} catch (SQLException e) {
// 例外の出力
e.printStackTrace();
}
}