CallableStatement对象
CallableStatement接口是用于执行SQL存储过程的接口,它继承自PreparedStatement接口。JDBC API提供了一个存储过程SQL转义语法,该语法允许对所有关系型数据库管理系统(RDBMS)使用标准方式调用存储过程。此语法有一个包含结果参数的形式和一个不包含结果参数的形式,具体如下所示:
{?= call <procedure-name>[(<arg1>,<arg2>, ...)]}
{call <procedure-name>[(<arg1>,<arg2>, ...)]}
在上述语法格式中,其中的参数(<arg1>,<arg2>, ...)有三种不同的形式 ,具体如下:
● IN 类型:此类型是用于参数从外部传递给存储过程使用
● OUT类型:此类型是存储过程执行过程中的返回值
● IN、OUT混合类型:此类型是参数传入,然后返回
如果使用结果参数,则必须将其注册为OUT参数。其他参数可用于输入、输出或同时用于二者。参数是根据编号按顺序引用的,第一个参数的编号是 1。
IN 参数值是使用继承自 PreparedStatement的setXxx()方法设置的。在执行存储过程之前,必须注册所有OUT参数的类型;它们的值是在执行后通过此类提供的getXxx()方法获取的。
CallableStatement可以返回一个ResultSet对象或多个ResultSet对象。多个ResultSet对象是通过继承Statement来处理的。
下面SQL语句用于在chapter01数据库中创建一个简单的存储过程:
DELIMITER //
CREATE PROCEDURE add_pro(a INT,b INT,OUT SUM INT)
BEGIN
SET SUM = a + b ;
END //
DELIMITER ;
上面程序创建了名为add_pro的存储过程,该存储过程包含3个参数:a、b是默认参数,即传入参数,而sum使用out修饰,是传出参数。
调用存储过程使用CallableStatement,可以通过Connection的prepareCall()方法来创建CallableStatement对象,创建该对象时需要传入调用存储过程的SQL语句,示例代码如下:
//使用Connection来创建一个CallableStatement对象
CallableStatement cstmt = conn.prepareCall("{call add_pro(?,?,?)}");
在上述示例代码中,?占位符可以是IN、OUT或者INOUT参数,这取决于储存过程add_pro。
存储过程的参数既有传入参数,也有传出参数。所谓传入参数就是Java程序必须为这些参数传入值,那么可以通过CallableStatement的setXxx()方法为传入的参数设置值;所谓传出参数就是Java程序可以通过该参数获取存储过程里的值,那么CallableStatement需要调用registerOutParameter()方法来注册该参数,示例代码如下所示:
//注册CallableStatement的第三个参数int类型
cstmt.registerOutParameter(3,Types.INTEGER);
经过上面步骤之后,就可以调用CallableStatement的execute()方法来执行存储过程了,执行结束后通过CallableStatement对象的getXxx(int index)方法来获取指定传出参数的值。为了让大家掌握如何调用存储过程,接下来,通过一个具体的案例来演示,如例1所示。
例1 Example03.java
1 package cn.itcast.jdbc.example;
2 import java.sql.CallableStatement;
3 import java.sql.Connection;
4 import java.sql.DriverManager;
5 import java.sql.Types;
6 public class Example03 {
7 public static void main(String[] args) throws Exception {
8 CallableStatement cstmt = null;
9 Connection conn = null;
10 try {
11 // 注册数据库的驱动
12 Class.forName("com.mysql.jdbc.Driver");
13 // 通过DriverManager获取数据库连接
14 String url = "jdbc:mysql://localhost:3306/chapter01";
15 String username = "root";
16 String password = "itcast";
17 conn = DriverManager.getConnection(url, username, password);
18 // 使用Connection来创建一个CallableStatement对象
19 cstmt = conn.prepareCall("call add_pro(?,?,?)");
20 cstmt.setInt(1, 4);
21 cstmt.setInt(2, 5);
22 // 注册CallableStatement的第三个参数为int类型
23 cstmt.registerOutParameter(3, Types.INTEGER);
24 // 执行存储过程
25 cstmt.execute();
26 System.out.println("执行结果是:" + cstmt.getInt(3));
27 // 回收数据库资源
28 } finally {
29 if (cstmt != null) {
30 cstmt.close();
31 }
32 if (conn != null) {
33 conn.close();
34 }
35 }
36 }
37 }
程序执行成功后,会将4和5两数相加的结果打印到控制台,具体如图1所示。
图1 运行结果
从图1中可以看出,运行结果正常。例1中第11~17行代码实现了注册数据库驱动和获取数据库连接的功能,第19~23行代码创建了一个CallableStatement对象用来调用数据库存储过程,该存储过程名为add_pro,并带有三个参数,其中第一、二个参数为输入参数,分别赋值为4和5,第三个为输出参数,第三个参数通过调用registerOutParameter()方法注册为int类型。第25行代码通过调用execute()方法,执行该存储过程。第26行代码用于输出该存储过程执行后的结果,即第一、二个参数相加之和。