可調用語句
JDBC 有另一個接口用於更複雜的場景。它繼承自PreparedStatement,稱為CallableStatement。
它用於調用(Call)數據庫中的存儲過程。這種調用的特殊性在於,除了ResultSet result 之外,還可以將參數傳遞給這種存儲過程。
你問什麼是新的?PreparedStatement也有一個ResultSet結果,您也可以將參數傳遞給它。是的,沒錯,但是存儲過程的特殊之處在於,它們不僅可以通過參數接收數據,還可以返回數據。
使用IN、OUT和INOUT參數調用存儲過程。它返回一個或多個ResultSet對象。Connection.prepareCall()方法用於創建CallableStatement對象。
假設您有一個存儲過程 ADD,它接受參數 a、b 和 c。此過程將 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 函數在第三個參數中返回相加的結果。只有CallableStatement對像對此一無所知。因此,我們通過調用registerOutParameter()方法明確地告訴他:
registerOutParameter(parameter number, Parameter type)
之後,您可以通過execute()方法調用該過程,然後使用getInt()方法從第三個參數讀取數據。
批處理請求
在實際項目中,經常會出現這樣的情況,你需要做很多同類型的查詢(本例中最常見的是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。
GO TO FULL VERSION