jdbc batch processing
このチュートリアルでは、サンプルのJavaの例を使用して、JDBCバッチ処理とJavaストアドプロシージャについて完全に理解します。
の中に JDBC例外処理 のチュートリアル JDBCチュートリアルシリーズ 、プログラミング例を使用してSQL例外を処理する方法を学びました。
このチュートリアルでは、JDBCドライバーを使用してJavaでバッチ処理を行う方法について説明します。また、ストアドプロシージャを作成し、Javaプログラムから呼び出す方法についても学習します。
バッチ処理とその利点を理解することから始めましょう。
学習内容:
JDBCバッチ処理
これは、1つのトランザクションで複数のSQLステートメントを実行するプロセスです。このプロセスにより、通信時間が短縮され、パフォーマンスが向上します。大量のデータの処理がはるかに簡単になります。
バッチ処理の利点
バッチ処理は、パフォーマンスとデータの整合性を向上させることを目的としています。
パフォーマンス
複数の(たとえば5つの)エントリがJAVAプログラムからテーブルに追加されるシナリオを考えてみます。簡単なアプローチは、データベースへの接続を開き、INSERTクエリを記述し、StatementまたはPreparedStatementを使用して各クエリを実行することです。
このアプローチでは、データベースへのネットワークトリップが増加し、その結果、パフォーマンスが低下します。バッチ処理を使用すると、この操作を1回の呼び出しで実行できます。
データの整合性
場合によっては、複数のテーブルにデータを挿入/更新する必要があります。これは、挿入または更新されるクエリのシーケンスが重要である相互に関連するトランザクションにつながります。実行中にエラーが発生すると、前のクエリで挿入されたデータがロールバックされます。
例:
#1) テーブル「EMPLOYEE_DETAILS」には3つの列があります。 ID 、 名前 、および 従業員の役割。
statement.execute('INSERT INTO EMPLOYEE_DETAILS(ID, NAME, ROLE) ' + 'VALUES ('1','EMPLOYEE_NAME1','ROLE1')');
#二) テーブル「EMPLOYEE_ADDRESS」には2つの列があります。 EMP ID そして 住所
statement.execute('INSERT INTO EMPLOYEE_ADDRESS( EMP_ID, ADDRESS) ' + 'VALUES ('1','ADDRESS1')');
上記の例では、最初のステートメントが正常に実行されたが、2番目のステートメントが失敗した場合に問題が発生する可能性があります。この状況では、最初のステートメントによって挿入されたデータのロールバックはありません。これにより、データの不整合が発生します。
最後にトランザクションをコミットするか、例外が発生した場合にロールバックを実行することで、データの整合性を実現できます。ただし、これを実現するには、ステートメントごとにDBを繰り返しヒットする必要があります。
一方、バッチ処理では、バッチ内のすべてのクエリが正常に実行された場合にのみ、データがコミットされます。そうでなければ、そうではありません。
バッチ処理の実行方法
StatementクラスとPreparedStatementクラスの両方で使用できるaddbatch()メソッドとexecuteBatch()メソッドを使用してバッチ処理を実行できます。
このチュートリアルでは、すべてのプログラムがJavaで記述されています。 Java8バージョンとOracleDBを使用しました。
=> Oracleソフトウェアをダウンロードするには、ここをクリックしてください
=> Javaバージョン8をダウンロードするには、ここをクリックしてください
次の例では、バッチ処理を入念に行う方法を説明します。ステップバイステップのJavaインストールプロセスがあります。
データを挿入する前のEMPLOYEEテーブルのデータ:
最高のビデオダウンローダーは何ですか
Javaプログラム
package com.STH.JDBC; import java.sql.BatchUpdateException; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class ExecuteBatch_Example { public static void main(String() args) throws ClassNotFoundException, SQLException { //Inserting the data in EMPLOYEE Table using the following query String insert_query1 = 'insert into employee values(?,?,?)'; Class.forName('oracle.jdbc.driver.OracleDriver'); Try(Connection conn = DriverManager.getConnection('jdbc:oracle:thin:system/pass123@localhost:1521:XE')) { PreparedStatement pstatemnt1 = conn.prepareStatement(insert_query1); //Setting values for the 1st person in EMPLOYEE Table pstatemnt1.setInt(1,10001); pstatemnt1.setString(2, 'Bush'); pstatemnt1.setString(3, 'William '); //Adding the 1st insert query into batch pstatemnt1.addBatch(); //Setting values for the 2nd person in EMPLOYEE Table pstatemnt1.setInt(1,10002); pstatemnt1.setString(2, “Bush'); pstatemnt1.setString(3, 'George'); //Adding the 2nd insert query into batch pstatemnt1.addBatch(); //Setting values for the 3rd person in EMPLOYEE Table pstatemnt1.setInt(1,10003); pstatemnt1.setString(2, 'Bond'); pstatemnt1.setString(3, 'James'); //Adding the 3rd insert query into batch pstatemnt1.addBatch(); //Executing the executeBatch method int No_of_Afffected_Rows()= pstatemnt1.executeBatch(); //After inserting the data, displaying no. of rows affected System.out.println('No of rows affected = ' +No_of_Afffected_Rows.length);} catch (SQLException e) { e.printStackTrace();} } }
出力:
データ挿入後のEMPLOYEEテーブルのデータ:
説明:
上記のプログラムでは、バッチ操作を使用して1回の呼び出しで3人の従業員のデータを挿入しました。
- 列の値を渡すための挿入クエリを1つ作成します。
- 接続を開き、接続オブジェクトを使用してpreparedStatementオブジェクトを作成し、prepareStatementメソッドを呼び出します。
- 次に、1の値を設定しますst従業員がsetXXXメソッドを使用し、addBatch()メソッドを呼び出して、バッチに新しい行を追加します。
- このように、2の値を追加しますndおよび3rd従業員。 addBatch()メソッドにクエリを追加した後、preparedStatementオブジェクトを使用してexecuteBatch()メソッドを呼び出す必要があります。
- executeBatch()メソッドは、3人の従業員のデータを1回の呼び出しで挿入します。
- データが正しく挿入されているかどうか、EMPLOYEEテーブルを確認してください。
Javaストアドプロシージャ
ストアドプロシージャは、単一のユニットを形成し、特定のタスクを実行するSQLステートメントのグループです。これらは、データベースサーバーで実行する一連の操作または質問を実行するために使用されます。さまざまなパラメータと結果を使用してコンパイルおよび実行できます。
各プロシージャには、参照する固有の名前があります。このサブプログラムユニットは、データベースオブジェクトとしてDBに保存されます。
サブプログラムは単なるプロシージャであり、必要に応じて手動で作成し、DBオブジェクトとして保存する必要があります。
ストアドプロシージャは、DBに格納できるプログラムのスタンドアロンブロックです。ストアドプロシージャの名前を使用して、それを呼び出して実行できます。これは主に、PL / SQLでプロセスを実行するために使用されます。プロシージャには、ネストされたブロックがある場合と、他のブロック内にネストされている場合があります。
ストアドプロシージャには3つの部分があります。
- 宣言部分(オプション): この部分では、変数、定数、カーソルなどを宣言できます。これはオプションの部分です。要件に応じて使用できます。
- 実行部分: この部分には、手順の主要なビジネスロジックが含まれています。通常、SQLステートメントのブロックがあります。
- 例外処理部分(オプション): このパートでは、Executionパートコードが原因で発生する可能性のある例外を処理できます。また、オプションです。
要件に基づいて、プロシージャを作成できます。パラメータから値を渡したり取得したりできます。
ストアドプロシージャで使用できるパラメータには3つのタイプがあります。彼らです:
- に: 入力値をストアドプロシージャに渡すために使用されます。ストアドプロシージャは、プログラムの入力パラメータを読み取り専用変数として使用します。サブプログラム内で値を変更することはできません。 Oracleは、パラメータのデフォルトモードとしてINを使用します。これはデフォルトのパラメータです。
- アウト: 実行後にストアドプロシージャから値を返すか、取得するために使用されます。これは、サブプログラム内の読み取り/書き込み変数です。値はサブプログラム内で変更できます。
- IN / OUT: これは、入力値をストアドプロシージャに渡し、プロシージャから値を返すか取得するためにも使用されます。読み取りと書き込みの両方が可能です。読んで変更することができます。
返品
returnキーワードを使用して、Javaプログラムなどのメインプログラムに制御を戻します。プロシージャがRETURNキーワードを見つけると、実行を終了し、その後のコードまたはステートメントをスキップします。
Javaからストアドプロシージャを呼び出す方法
ストアドプロシージャを呼び出すためのJavaのCallableStatementインターフェイスがあります。 CallableStatementインターフェイスオブジェクトは、ConnectionインターフェイスのprepareCall()メソッドを使用して作成できます。その後、executeQuery()メソッドを呼び出して、Javaプログラムでストアドプロシージャを実行する必要があります。
これを実装するJavaプログラムを作成する前に、プログラムで使用するためのストアドプロシージャを作成する必要があります。
以下は、Javaプログラムでストアドプロシージャを呼び出すための構文です。
構文 | パラメータの数 |
---|---|
{PROCEDURE_NAME()を呼び出す} | 入力パラメーターも出力パラメーターもありません |
{PROCEDURE_NAME(?、?、?)を呼び出す} | 3つの入力パラメーターと出力パラメーターなし |
{?= PROCEDURE_NAME()を呼び出す} | 入力パラメーターなしと1つの出力パラメーター(RETURN値) |
{?= PROCEDURE_NAME(?、?)を呼び出す} | 2つの入力パラメーターと1つの出力パラメーター(RETURN値) |
ストアドプロシージャを作成する手順
#1) DBサーバーでプロシージャを作成します。ここでは、OracleDBを使用しています。
#2)完全なプロシージャを作成するための構文:
ストアドプロシージャはJavaコードでも記述できます。
#3) INパラメータとOUTパラメータを渡して、プロシージャで使用します。
#4) AS / ISキーワードを記載する必要があります。新しいプロシージャに別のプロシージャを追加する場合は、ISキーワードを使用するか、プロシージャがスタンドアロンの場合はASキーワードを使用します。
#5) 作成できる要件に基づいて、変数を宣言します。これは必須ではありません。
#6) 次に、BEGINキーワードを使用してプロシージャをBEGINし、プロシージャで実行するSQLステートメントまたはクエリを記述します。
# 7) 次に、Exception部分で例外を処理できます。言及することも必須ではありません。
#8) ENDキーワードとプロシージャー名を指定して、プロシージャーを終了します。
Oracleでプロシージャを作成し、一意の名前で保存して、Javaプログラムからそのプロシージャを呼び出すことができます。プロシージャを作成し、Javaでそのプロシージャを呼び出すこともできます。
Oracleでプロシージャを作成して保存し、Javaプログラムでプロシージャを呼び出します。
#1) データベースサーバーを開きます。ここでは、OracleDBサーバーを使用しています。
#二) プロシージャフォルダを右クリックし、(新しいプロシージャ)オプションをクリックします。
#3) プロシージャの名前とパラメータの詳細を尋ねられます。
注意: プロシージャの作成中にパラメータの詳細を指定することもできます。
#4) このチュートリアルですでに説明した手順を使用して手順を記述し、一意の名前で手順を保存します。
スクリーンショットの手順では、出力がDBに表示されます。 Javaプログラムでも表示するように変更できます。そのためには、OUTパラメータを使用する必要があります。
#5) 実行ボタンをクリックして手順を実行します
#6) (入力値)列に値を入力します。指定された値のデータが表示されます。
これまで、DBコンソール自体でプロシージャを作成して実行する方法を見てきました。
DBでプロシージャを作成します。それを呼び出して、Javaコンソールにデータを表示します 。
上記の手順を使用して次のプロシージャを作成し、「DISPLAY_EMPLOYEE_DETAILS」という名前で保存します。
Javaストアドプロシージャのサンプルプログラム
package com.STH.JDBC; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; public class StoredProcedureExample { public static void main(String() args) throws ClassNotFoundException { Class.forName('oracle.jdbc.driver.OracleDriver'); //Connecting to Oracle DB Try (Connection conn = DriverManager.getConnection('jdbc:oracle:thin:system/pass123@localhost:1521:XE')) { // Creating prepared Statement CallableStatementCallStmt = conn.prepareCall('{call DISPLAY_EMPLOYEE_DETAILS(?,?,?,?)}'); //Passing Input Parameter CallStmt.setInt(1,1001); //Retrieving the Output Parameters values CallStmt.registerOutParameter(2, java.sql.Types.VARCHAR); CallStmt.registerOutParameter(3, java.sql.Types.VARCHAR); CallStmt.registerOutParameter(4, java.sql.Types.VARCHAR); //Calling the execute to execute the procedure and retrieve the data CallStmt.execute(); System.out.println('First Name: '+ CallStmt.getString(2)+'
Last Name: '+ CallStmt.getString(3) + '
Email: ' + CallStmt.getString(4)); }catch (SQLException e) { e.printStackTrace(); } } }
出力:
説明:
上記のプログラムでは、1つのプロシージャを作成し、それをOracleDBに保存しました。次に、CallableStatementを使用してそのプロシージャを呼び出し、Javaコンソールにデータを表示しました。
- プロシージャを作成し、OracleDBに保存します。
- Javaプログラムで、DB接続を開き、接続オブジェクトとCallableStatementオブジェクトを使用してprepareCallメソッドを呼び出します。
- setXXXメソッドを使用して入力パラメーター値を渡します。
- registerOutParameterメソッドを使用して出力パラメーター値を取得します。このメソッドでは、パラメーターのインデックス値とパラメーターのデータ型を渡す必要があります。パラメータインデックスに値を格納します。
- getXXXメソッドを使用して、データを取得し、Javaコンソールに表示できます。
プロシージャを作成し、Javaプログラム自体で実行します。
Javaプログラム
package com.STH.JDBC; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Statement; public class StoredProcedureExample1 { public static void main(String() args) throws ClassNotFoundException { String Stored_Procedure = 'CREATE OR REPLACE PROCEDURE UPD_EMPLOYEE_DETAILS
' +'(
' + ' PARAM1 IN NUMBER,
' + ' PARAM2 IN NUMBER
'+ ') IS
'+ ' BEGIN
'+ 'UPDATE EMPLOYEE_DETAILS SET EMPNUM= PARAM2 WHERE EMPNUM = PARAM1;
'+ 'COMMIT;
'+ 'END UPD_EMPLOYEE_DETAILS;
'; Class.forName('oracle.jdbc.driver.OracleDriver'); //Connecting to Oracle DB try(Connection conn = DriverManager.getConnection('jdbc:oracle:thin:system/pass123@localhost:1521:XE')) {// Creating prepared Statement Statement stmt = conn.createStatement(); CallableStatementCallStmt = conn.prepareCall('{call UPD_EMPLOYEE_DETAILS(?,?)}'); stmt.execute(Stored_Procedure); //Setting the values to pass the procedure CallStmt.setInt(1,1010); CallStmt.setInt(2, 10010); //Calling executeUpdate method to update the values using Procedure CallStmt.executeUpdate(); System.out.println(' Successfully Updated ' ); } catch (SQLException e) { e.printStackTrace(); } } }
出力:
プログラムの実行前のEmployee_detailsテーブルのデータ:
プログラム実行後のEmployee_detailsテーブルのデータ:
説明:
上記のプログラムでは、プロシージャコードを文字列として格納します。
String Stored_Procedure = 'CREATE OR REPLACE PROCEDURE UPD_EMPLOYEE_DETAILS
' +'(
' +' PARAM1 IN NUMBER,
' +' PARAM2 IN NUMBER
'+ ') IS
'+' BEGIN
'+'UPDATE EMPLOYEE_DETAILS SET EMPNUM= PARAM2 WHERE EMPNUM = PARAM1;
'+'COMMIT;
'+'END UPD_EMPLOYEE_DETAILS;
';
- Oracle DB Connectionを開き、接続オブジェクトを使用してステートメント・オブジェクトを作成します。
- Javaコードでプロシージャを作成しているため、ステートメントオブジェクトを使用してcreateStatementメソッドを呼び出します。
- 構文を使用してプロシージャを呼び出す {UPD_EMPLOYEE_DETAILS(?、?)を呼び出す CallableStatementのprepareCallメソッド。
- Javaコードでプロシージャを作成しているので、その「プロシージャコードの作成」を実行する必要があります。
- そのプロシージャを実行するには、Statementオブジェクトを使用してexecuteメソッドを呼び出します。 stmt.execute(Stored_Procedure) 」。これにより、DBにプロシージャが一時的に作成されます。
- プロシージャのスコープは、プログラムの実行の終了です。それ以降はご利用いただけなくなります。 setXXXメソッドを使用して、Employee_Detailsテーブルで更新する値を設定します。
- callableStatementオブジェクトを使用してexecuteUpdateメソッドを呼び出します。このメソッドは、Empoyee_Detailsテールの値を更新します。
- データが適切に更新されているかどうか、Employee_detailsテーブルを確認してください。
覚えておくべきポイント:
- バッチ処理により、パフォーマンスが向上し、データの整合性が維持されます。
- 1つのトランザクションで複数のSQLステートメントを実行することをバッチ処理と呼びます。
- ストアドプロシージャは、ビジネスロジックを実行するために使用されるSQLステートメントのブロックです。
- INキーワードを使用して入力パラメーターをプロシージャーに渡し、OUTキーワードを出力パラメーターに渡すことができます。
- DBサーバー自体にプロシージャを作成し、一時的にJavaコードを使用することもできます。
よくある質問
Q#1)JDBCでバッチ処理を実行するには、どのインターフェイスを使用する必要がありますか?
回答: Javaパッケージには、バッチ処理を行うためのメソッドを提供するStatementおよびPreparedStatementインターフェースがあります。
Q#2)バッチ更新はJDBCでどのように機能しますか?
回答: JDBCバッチ更新は、更新を1つずつ送信するのではなく、グループ化してデータベースに一度に送信する一連の更新です。したがって、データベース内のネットワークトラフィックが減少します。
Windows10用のフリーウェアレジストリクリーナー
Q#3)バッチ処理はどのようにパフォーマンスを向上させますか?
回答: バッチ処理では、データを1つずつ送信するのではなく、一度に(1ラウンドトリップのみ)データベースに送信します。データベースは、いくつかのステートメントを並行して実行できる場合があります。このように、アプリケーションのパフォーマンスが向上し、時間が節約されます。
Q#4)JDBCのストアドプロシージャで受け入れられるパラメータは何ですか?
回答: パラメータには、IN、OUT、およびINOUTパラメータの3つのタイプがあります。 INパラメータは、入力値を取得するためのものです。 OUTパラメータは、出力値を取得するためのものです。 INOUTパラメーターは、入力と出力の両方に使用されます。
Q#5)JDBCでストアドプロシージャを実行するために使用できる方法は何ですか?
回答: CallableStatementインターフェイスを使用して、プロシージャを呼び出すことができます。 CallableStatementインターフェイスは、ストアドプロシージャを実行するための3つのメソッドを提供します。
3つの方法は次のとおりです。
- executeUpdate(): プロシージャが戻り値を返さない場合は、このメソッドを使用します。
- executeQuery(): プロシージャが1つの結果セットのみを返す場合は、このメソッドを使用します。
- execute(): プロシージャが多数の結果セットまたは不明な数の結果セットを返す場合は、このメソッドを使用します。
結論
このチュートリアルでは、バッチ処理とストアドプロシージャについて説明しました。現代の世界では、高性能、データの整合性、および再利用性が、一般的なアプリケーションの流行語です。バッチ処理とストアドプロシージャの両方が、これらの機能を実装する上で非常に重要な役割を果たします。これらの知識は、すべてのソフトウェアエンジニアにとって避けられません。