CallableStatement

JDBC には、さらに複雑なシナリオ用の別のインターフェイスがあります。これはPreparedStatementを継承しており、 CallableStatementと呼ばれます。

データベース内のストアド プロシージャを呼び出す (Call) ために使用されます。このような呼び出しの特徴は、 ResultSet の結果に加えて、パラメーターもそのようなストアド プロシージャに渡すことができることです。

何が新しいのですか?PreparedStatement にはResultSet結果もあり、それにパラメータを渡すこともできます。はい、そのとおりですが、ストアド プロシージャの特徴は、パラメータを通じてデータを受け取るだけでなく返すこともできることです。

ストアド プロシージャは、 INOUT、およびINOUTパラメータを使用して呼び出されます。1 つ以上のResultSetオブジェクトを返します。Connection.prepareCall()メソッドは、 CallableStatementオブジェクトを作成するために使用されます。

ここで、パラメーター a、b、c を受け入れるストアド プロシージャ ADD があると想像してください。このプロシージャは、a と b を加算し、加算結果を変数 c に代入します。

呼び出してみるコードを書いてみましょう。

// Connect to the server
Connection connection = DriverManager.getConnection("jdbc:as400://mySystem");

// Create a CallableStatement object. It does preprocessing
// calling a stored procedure. Question marks
// indicate where the input parameters should be substituted, and where the output ones
// The first two parameters are input,
// and the third one is a day off.
CallableStatement statement = connection.prepareCall("CALL MYLIBRARY.ADD (?, ?, ?)");

// Setting up input parameters. Passing 123 and 234 to the procedure
statement.setInt (1, 123);
statement.setInt (2, 234);

// Registering the output parameter type
statement.registerOutParameter (3, Types.INTEGER);

// Run stored procedure
statement.execute();

// Get the value of the output parameter
int sum = statement.getInt(3);

// Close CallableStatement and Connection
statement.close();
connection.close();

作業はPreparedStatementとほぼ似ていますが、ニュアンスが異なります。ADD 関数は、3 番目のパラメーターで加算の結果を返します。CallableStatementオブジェクトだけがこれについて何も知りません。したがって、registerOutParameter()メソッドを呼び出して、これを明示的に彼に伝えます。

registerOutParameter(parameter number, Parameter type)

その後、 execute()メソッドを通じてプロシージャを呼び出し、 getInt()メソッドを使用して 3 番目のパラメータからデータを読み取ることができます。

リクエストのバッチ処理

実際のプロジェクトでは、同じタイプのクエリ (この場合最も一般的なのはPreparedStatement ) を多数作成する必要がある状況がよく発生します。たとえば、数十または数百のレコードを挿入する必要があります。

各リクエストを個別に実行すると、時間がかかり、アプリケーションのパフォーマンスが低下します。これを防ぐには、バッチ挿入モードを使用します。それは、リクエストを含むバッファを蓄積し、すぐに実行するという事実にあります。

例としてコードの一部を示します。

PreparedStatement stmt = con.prepareStatement(
        	"INSERT INTO jc_contact (first_name, last_name, phone, email) VALUES (?, ?, ?, ?)");

for (int i = 0; i < 10; i++) {
	// Fill in the request parameters
	stmt.setString(1, "FirstName_" + i);
    stmt.setString(2, "LastNAme_" + i);
    stmt.setString(3, "phone_" + i);
    stmt.setString(4, "email_" + i);
	// The request is not executed, but fits into the buffer,
	// which is then executed immediately for all commands
	stmt.addBatch();
}
// Execute all requests at once
int[] results = stmt.executeBatch();

クエリをexecute()メソッドで実行する代わりに、 addBatch()メソッドでバッチ処理します。

そして、数百のリクエストがある場合は、executeBatch ()コマンドを呼び出すことで、それらをすべて一度にサーバーに送信できます。

健康。executeBatch()メソッドは、整数の配列 int[] を返します。この配列の各セルには、対応するクエリによって変更された行の数を示す数値が含まれています。バッチ内のリクエスト番号 3 が 5 行を変更した場合、配列の 3 番目のセルには数値 5 が含まれます。