CallableStatement
JDBC có một giao diện khác cho các kịch bản phức tạp hơn. Nó kế thừa từ PreparedStatement và được gọi là CallableStatement .
Nó dùng để gọi (Call) các thủ tục lưu sẵn trong cơ sở dữ liệu. Điểm đặc biệt của cuộc gọi như vậy là, ngoài kết quả của Bộ kết quả , các tham số cũng có thể được chuyển đến một thủ tục được lưu trữ như vậy.
Có gì mới, bạn yêu cầu? PreparedStatement cũng có một kết quả ResultSet và bạn cũng có thể truyền tham số cho nó. Vâng, đúng vậy, nhưng điểm đặc biệt của các thủ tục được lưu trữ là thông qua các tham số, chúng không chỉ có thể nhận mà còn có thể trả về dữ liệu.
Thủ tục lưu sẵn được gọi với các tham số IN , OUT và INOUT . Nó trả về một hoặc nhiều đối tượng ResultSet . Phương thức Connection.prepareCall() được sử dụng để tạo đối tượng CallableStatement .
Ở đây hãy tưởng tượng rằng bạn có một thủ tục lưu trữ ADD chấp nhận các tham số a, b và c. Thủ tục này cộng a và b và đặt kết quả của phép cộng vào biến c.
Hãy viết mã nơi chúng tôi sẽ cố gắng gọi nó:
// 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();
Công việc gần giống như với PreparedStatement , chỉ có một sắc thái. Hàm ADD của chúng tôi trả về kết quả của phép cộng trong tham số thứ ba. Chỉ đối tượng CallableStatement không biết gì về điều này. Do đó, chúng tôi nói với anh ấy điều này một cách rõ ràng bằng cách gọi phương thức registerOutParameter() :
registerOutParameter(parameter number, Parameter type)
Sau đó, bạn có thể gọi thủ tục thông qua phương thức exec() và sau đó đọc dữ liệu từ tham số thứ ba bằng cách sử dụng phương thức getInt() .
Yêu cầu hàng loạt
Trong các dự án thực tế, một tình huống thường phát sinh khi bạn cần thực hiện nhiều loại truy vấn giống nhau (phổ biến nhất trong trường hợp này là PreparedStatement ), chẳng hạn như bạn cần chèn vài chục hoặc hàng trăm bản ghi.
Nếu bạn thực hiện riêng lẻ từng yêu cầu sẽ mất rất nhiều thời gian và giảm hiệu suất của ứng dụng. Để tránh điều này, bạn có thể sử dụng chế độ chèn hàng loạt. Thực tế là bạn tích lũy một số bộ đệm với các yêu cầu của mình và sau đó thực hiện chúng ngay lập tức.
Đây là một đoạn mã làm ví dụ:
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();
Thay vì thực hiện truy vấn bằng phương thức exec() , chúng ta gộp truy vấn đó bằng phương thức addBatch() .
Và sau đó, khi có hàng trăm yêu cầu, bạn có thể gửi tất cả chúng cùng một lúc đến máy chủ bằng cách gọi lệnh execBatch() .
Khỏe mạnh. Phương thức execBatch() trả về một mảng các số nguyên — int[]. Mỗi ô trong mảng này chứa một số cho biết số hàng được sửa đổi bởi truy vấn tương ứng. Nếu yêu cầu số 3 trong lô thay đổi 5 hàng, thì ô thứ 3 của mảng sẽ chứa số 5.
GO TO FULL VERSION