0
Help us understand the problem. What are the problem?

posted at

updated at

Java データベース トランザクション(INSERT編)

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にはデータベース名を、USERPASSには、データベースに登録したユーザ名とパスワードを設定します。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オブジェクトのsetIntsetStringメソッドで、第一引数にプレースホルダの位置を渡し、第二引数に値を渡すことで、SQL文の"?"(プレースホルダ)にパラメータを設定します。

prst.setInt(1, 5);
prst.setString(2, "vellfire");

トランザクションをバッチ処理に登録後、SQLを実行しコミットを行います。

prst.addBatch();
prst.executeBatch();
con.commit();

catchブロック

catchブロックではClassNotFoundExceptionSQLExceptionを検査例外として捉えます。ClassNotFoundExceptiontryブロックので行った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();
  }
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Sign upLogin
0
Help us understand the problem. What are the problem?