可调用语句

JDBC 有另一个接口用于更复杂的场景。它继承自PreparedStatement,称为CallableStatement

它用于调用(Call)数据库中的存储过程。这种调用的特殊性在于,除了ResultSet result 之外,还可以将参数传递给这种存储过程。

你问什么是新的?PreparedStatement也有一个ResultSet结果,您也可以将参数传递给它。是的,没错,但是存储过程的特殊之处在于,它们不仅可以通过参数接收数据,还可以返回数据。

使用INOUTINOUT参数调用存储过程。它返回一个或多个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。