Java >> Java チュートリアル >  >> Tag >> Jdbc

JDBC でのバッチ処理

1.はじめに

Java Database Connectivity (JDBC) は、データベースとの対話に使用される Java API です。バッチ処理では、複数のクエリを 1 つのユニットにグループ化し、1 回のネットワーク トリップでデータベースに渡します。

この記事では、SQL クエリのバッチ処理に JDBC を使用する方法について説明します。

JDBC の詳細については、こちらの紹介記事をご覧ください。

2.バッチ処理を行う理由

バッチ処理を行う主な動機は、パフォーマンスとデータの一貫性です。

2.1.パフォーマンスの向上

一部のユース ケースでは、大量のデータをデータベース テーブルに挿入する必要があります。 JDBC を使用する場合、バッチ処理を使用せずにこれを実現する方法の 1 つは、複数のクエリを順番に実行することです。

データベースに送信されるシーケンシャル クエリの例を見てみましょう:

statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('1','EmployeeName1','Designation1')"); 
statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('2','EmployeeName2','Designation2')");

これらの連続した呼び出しにより、データベースへのネットワーク トリップの数が増加し、パフォーマンスが低下します。

バッチ処理を使用すると、これらのクエリを 1 回の呼び出しでデータベースに送信できるため、パフォーマンスが向上します。

2.2.データの一貫性

特定の状況では、データを複数のテーブルにプッシュする必要があります。これは、プッシュされるクエリのシーケンスが重要な、相互に関連するトランザクションにつながります。

実行中にエラーが発生すると、以前のクエリによってプッシュされたデータがあればロールバックされます。

複数のテーブルにデータを追加する例を見てみましょう:

statement.execute("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('1','EmployeeName1','Designation1')"); 
statement.execute("INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) "
 + "VALUES ('10','1','Address')");

上記のアプローチの典型的な問題は、最初のステートメントが成功し、2 番目のステートメントが失敗したときに発生します。 この状況では、最初のステートメントによって挿入されたデータのロールバックがないため、データの不整合が発生します。

トランザクションを複数の挿入/更新にまたがり、最後にトランザクションをコミットするか、例外が発生した場合はロールバックを実行することで、データの一貫性を実現できますが、この場合でも、ステートメントごとにデータベースに繰り返しアクセスしています.

3.バッチ処理の方法

JDBC には、Statement という 2 つのクラスがあります。 および PreparedStatement データベースでクエリを実行します。どちらのクラスにも、addBatch() の独自の実装があります。 そしてexecuteBatch() バッチ処理機能を提供するメソッド

3.1. ステートメントを使用したバッチ処理

JDBC では、データベースに対してクエリを実行する最も簡単な方法は、 Statement を使用することです。 オブジェクト.

まず、addBatch() を使用します すべての SQL クエリをバッチに追加し、executeBatch() を使用してそれらの SQL クエリを実行できます。 .

executeBatch() の戻り型 int です 各 SQL ステートメントの実行によって影響を受けたレコードの数を示す配列。

ステートメントを使用してバッチを作成および実行する例を見てみましょう:

Statement statement = connection.createStatement();
statement.addBatch("INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES ('1','EmployeeName','Designation')");
statement.addBatch("INSERT INTO EMP_ADDRESS(ID, EMP_ID, ADDRESS) "
 + "VALUES ('10','1','Address')");
statement.executeBatch();

上記の例では、EMPLOYEE にレコードを挿入しようとしています。 および EMP_ADDRESS Statement を使用したテーブル .実行されるバッチに SQL クエリがどのように追加されているかがわかります。

3.2. PreparedStatement を使用したバッチ処理

PreparedStatement SQLクエリを実行するために使用される別のクラスです SQL ステートメントの再利用が可能になり、更新/挿入ごとに新しいパラメーターを設定する必要があります。

PreparedStatement を使用した例を見てみましょう。 まず、文字列としてエンコードされた SQL クエリを使用してステートメントを設定します。

String[] EMPLOYEES = new String[]{"Zuck","Mike","Larry","Musk","Steve"};
String[] DESIGNATIONS = new String[]{"CFO","CSO","CTO","CEO","CMO"};

String insertEmployeeSQL = "INSERT INTO EMPLOYEE(ID, NAME, DESIGNATION) "
 + "VALUES (?,?,?)";
PreparedStatement employeeStmt = connection.prepareStatement(insertEmployeeSQL);

次に、String の配列をループします。 値を入力し、新しく構成されたクエリをバッチに追加します。

ループが終了したら、バッチを実行します:

for(int i = 0; i < EMPLOYEES.length; i++){
    String employeeId = UUID.randomUUID().toString();
    employeeStmt.setString(1,employeeId);
    employeeStmt.setString(2,EMPLOYEES[i]);
    employeeStmt.setString(3,DESIGNATIONS[i]);
    employeeStmt.addBatch();
}
employeeStmt.executeBatch();

上記の例では、EMPLOYEE にレコードを挿入しています。 PreparedStatement を使用したテーブル。 挿入する値がどのようにクエリに設定され、バッチに追加されて実行されるかを確認できます。

4.結論

この記事では、JDBC を使用してデータベースと対話する際に、SQL クエリのバッチ処理がいかに重要であるかを説明しました。

いつものように、この記事に関連するコードは Github にあります。


Java タグ