可调用语句
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