Java 数据库编程4---CallableStatement接口

CallableStatement主要是调用数据库中的存储过程,CallableStatement也是Statement的子接口。在使用CallableStatement时可以接收过程的返回值,此接口的常用方法如下表所示。

序号 方法 描述
1 int getInt(int parameterIndex) 根据编号取出过程的int类型返回值
2 float getFloat(int parameterIndex) 根据编号取出纯纯过程的float类型返回值
3 void setInt(String parameterName, int x) 将指定的参数名称设置为给定的Java int值。
4 void setFloat(String parameterName, float x) 将指定的参数名称设置为给定的Java float值。
5 void registerOutParameter(int parameterIndex, int sqlType) 设置返回值的类型,需要使用Types类

在JDBC中,如果要设置过程的返回值类型,可以使用Types完成。在Types中定义了很过常量,如果现在返回类型为int,则可以使用Types.INTEGER.
下面是JDBC操作存储过程的例子,这里先在cmd命令行进入mysql

mysql -uroot -p

然后输入密码:root,进入mysql.
登录mysql
选择usersinfo数据库:

use usersinfo;

选择usersinfo数据库
然后,开始创建一个存储过程myproc:

delimiter #
drop procedure myproc #
create procedure myproc(in p1 int,inout p2 int,out p3 int)
begin
    select p1,p2,p3;
    set p1=10;
    set p2=20;
    set p3=30;
    end
#
delimiter  ;

运行效果:
创建存储过程
在myproc的存储过程中,定义了三个变量,分别使用in,inout,out 三种类型声明,这三种类型的声明含义如下
in类型的,只用于将值传递到存储过程中,不能向外传出数据也就是调用存储过程时x1可以赋值给p1。但是在存储过程运行中,修改p1的值对x1不会有任何影响。
inout类型,即可将值传到存储过程中,又可以从存储过程中向外传出数据也就是说调用存储过程时,x2可以赋值给p2。在存储过程运行中修改p2,x2也会跟着改变。
out类型只用于存储过程向外传递数据,不能用于传入数据也就是说调用存储过程时,当x3的值不能传递给p3。在存储过程运行中修改了p3,x3的值也会跟着改变。

接着来设置三个变量x1,x2x3

set @x1=70;
set @x2=80;
set @x3=90;

然后来调用存储过程:

call myproc(@x1,@x2,@x3);

运行结果:
调用存储过程

分析:
在存储过程myproc中的
第一条语句:select p1,p2,p3;
这条语句把传入到存储过程的参数输出一下,可以看到第一个参数p1=x1=70,第二个参数p2=x2=80,第三个参数p3=null;
可以看到x1传递给p1成功,x2传递给p2也成功,x3不能传值给p3
第二条语句:set p1=10;
这条语句把形式参数p1的值修改成10,但是p1是in类型的,所以p1的修改不影响x1,x1的值还是原来的70.
第三条语句:set p2=20;
这条语句把形式参数p2的值修改成20,因为p2是inout类型的,所以修改了p2,x2的值也会跟着改变,不再是原来的值,而是变成新的值20.
第四条语句:set p3=30;
这条语句把形式参数p3的值改成30,因为p3的值是out类型的,所以,修改了p3的值为30,x3也会变成30;
下面就来输出x1,x2,x3三个变量来验证上面说的对不对:

select @x1,@x2,@x3;

运行结果:
x1,x2,x3的值
可以看到x1=70不变,而x2=p2=20,x3=p3=30
从上面的结果可以发现,in操作只是将值传递进去,而本身不会被过程修改。而inout操作,即可以传递值,也可以被存储过程修改。out操作不能传递值,但可以被存储过程修改。
实例:使用jdbc调用myproc存储过程

package my.proc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.CallableStatement;
import java.sql.Types;

public class ProcDemo
{
    // 定义MySQL的数据库驱动程序
    public static final String driver = "com.mysql.jdbc.Driver";
    // 定义MySQL数据库的连接地址
    public static final String url = "jdbc:mysql://localhost:3306/usersinfo";
    // MySQL数据库的连接用户名
    public static final String user = "root";
    // MySQL数据库的连接密码
    public static final String password = "root";

    public static void main(String args[]) throws Exception
    { 
        // 数据库连接
        Connection conn = null; 
        // 数据库存储过程操作
        CallableStatement cstmt = null;
        //调用存储过程的SQL语句
        String sql = "{call myproc(?,?,?)}";
        // 加载驱动程序
        Class.forName(driver); 
        //建立数据库连接
        conn = DriverManager.getConnection(url, user, password);
        //实例化数据库存储过程操作
        cstmt = conn.prepareCall(sql);
        //设置设置第一个输入参数
        cstmt.setInt(1, 70);
        //设置第二个输入参数
        cstmt.setInt(2, 80); 
        cstmt.setInt(3, 90);
        //不能给输入参数注册输出类型
        //Exception in thread "main" java.sql.SQLException: Parameter number 1 is not an OUT parameter
//      cstmt.registerOutParameter(1, Types.INTEGER);

        //设置第一个输出参数的输出类型
        cstmt.registerOutParameter(2, Types.INTEGER);
        //设置第二个输出参数的输出类型
        cstmt.registerOutParameter(3, Types.INTEGER);
        //输出编译好的存储过程操作语句
        String toString=cstmt.toString();
        System.out.println("mysql>"+toString.substring(toString.lastIndexOf(":")+1).trim());
        //执行存储过程调用
        cstmt.execute(); // 执行过程
        //不能获取in类型的输出
//      System.out.println("in参数的返回值:" + cstmt.getInt(1));
        System.out.println("inout参数的返回值:" + cstmt.getInt(2));
        System.out.println("out参数的返回值:" + cstmt.getInt(3));
        cstmt.close();
        conn.close(); // 数据库关闭
    }
}

运行结果:

mysql>CALL myproc(70,80,90)
inout参数的返回值:20
out参数的返回值:30

可以看到,和我们手动操作数据库一样,inout,out类型的参数在过程中被修改都会影响输出值。

猜你喜欢

转载自blog.csdn.net/qq_21808961/article/details/80968216