JDBC调用存储过程和函数

1 CallableStatement接口

CallableStatement接口用于调用存储过程和函数。

通过使用存储过程和函数,我们可以在数据库上编写业务逻辑,这将使性能更好,因为它们是预编译的。

2 存储过程和函数的区别?

存储过程 函数
用于执行业务逻辑。 用于执行运算。
没有返回值类型。 必须有返回值类型。
可以返回0个或多个值。 可能仅返回一个值。
可以从存储过程中调用函数。 无法从函数调用存储过程。
支持输入和输出参数。 仅支持输入参数。
可以在存储过程中使用try/catch块处理异常。 无法在存储过程中使用try/catch块处理异常。

3 获取CallableStatement对象

Connection接口的prepareCall() 方法返回CallableStatement对象。语法如下:

public CallableStatement prepareCall("{ call procedurename(?,?...?)}");

下面给出了获取CallableStatement对象代码示例:

CallableStatement stmt=con.prepareCall("{call myprocedure(?,?)}");

上面代码调用了接收2个参数(可能是输入参数或输出参数)的存储过程:myprocedure。

4 调用存储过程的示例

4.1 创建存储过程

在MySQL的test数据库中,执行以下SQL创建pro_insert_user存储过程:

DELIMITER $$
CREATE PROCEDURE pro_insert_user(username VARCHAR(50),PASSWORD VARCHAR(50))
BEGIN

INSERT INTO t_user(username,PASSWORD) VALUES(username,PASSWORD); 

END $$

存储过程中涉及的t_user表的表结构如下:

CREATE TABLE `t_user` (
   `id` int(11) NOT NULL AUTO_INCREMENT,
   `username` varchar(50) DEFAULT NULL,
   `password` varchar(50) DEFAULT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8

4.2 编写示例代码

CallProDemo:

package com.yiidian;

import java.io.*;
import java.sql.*;

/**
 * 一点教程网 - http://www.yiidian.com
 */
public class CallProDemo {
    public static void main(String args[])throws Exception {
        try {
            Class.forName("com.mysql.jdbc.Driver");

            Connection con = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/test", "root", "root");

            CallableStatement stmt=con.prepareCall("{call pro_insert_user(?,?)}");
            stmt.setString(1,"mark");
            stmt.setString(2,"123");
            stmt.execute();

            System.out.println("存储过程调用成功!");

            con.close();
        }catch(Exception e){
            System.out.println(e);
        }
    }
}

4.3 运行测试

执行完毕程序后,查看t_user表是否多了一条记录:

5 调用函数的示例

在下面的示例中,我们调用pro_sum函数,该函数接收两个输入参数并返回给定数字的总和。在这里,我们使用到了CallableStatement接口的registerOutParameter() 方法,该方法将输出参数注册为其相应的类型。它向CallableStatement提供有关所显示结果类型的信息。

Types类定义了许多常量如INTEGER,VARCHAR,FLOAT,DOUBLE,BLOB,CLOB等。

5.1 创建存储过程

在MySQL的test数据库中,执行以下SQL创建fun_sum函数:

DELIMITER $$
CREATE FUNCTION fun_sum(n1 INT,n2 INT)
RETURNS INT
BEGIN

DECLARE total INT;  
SET total = n1+n2;  
RETURN total;

END $$

5.2 编写示例代码

CallFunDemo:

package com.yiidian;

import java.io.*;
import java.sql.*;

/**
 * 一点教程网 - http://www.yiidian.com
 */
public class CallFunDemo {
    public static void main(String args[])throws Exception {
        try {
            Class.forName("com.mysql.jdbc.Driver");

            Connection con = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/test", "root", "root");

            CallableStatement stmt=con.prepareCall("{?= call fun_sum(?,?)}");
            stmt.setInt(2,10);
            stmt.setInt(3,43);
            stmt.registerOutParameter(1,Types.INTEGER);
            stmt.execute();

            System.out.println(stmt.getInt(1));

            con.close();
        }catch(Exception e){
            System.out.println(e);
        }
    }
}

5.3 运行测试