JDBC从入门到放弃-04:JDBC的callableStatement

JDBC从入门到放弃

04-JDBC的callableStatement

第一节我们看到JDBC支持的数据库操作除了statement和preparedSatement以外还支持callableStatement。上面两节讲解了statement和preparedStatement的内容,这节我们继续讲解callableStatement的内容,也就是所谓的存储过程。

什么是存储过程

SQL中的存储过程类似于java中的函数(方法)。

存储过程:预先编辑好SQL语句的集合,这个集合完成了某项具体的功能集合,我需要这个功能的时候,只要调用这个过程就好了!(一般大型的企业项目才会用到,中小型的项目不会使用到,这里作为了解即可)

创建语法

create procedure 存储过程的名字(参数列表)

begin

存储过程体(SQL语句的集合);

end

注意:

  1. 参数列表包含三个部分:参数模式 参数名 参数类型

(比如: in s_name varchar(20) )

参数模式:

in : 该参数可以作为输入,需要调用方传入值来给存储过程

out : 该参数可以作为输出,该参数可以作为返回值给调用方

inout : 该参数既可以做输入,也可以作为输出

  1. 如果存储体只要一句SQL语句,begin和end可以省略,存储体里的slq语句结尾处必须加分号,避免数据库误判为存储过程的结束标记,所以需要我们自定义命令的结尾符号:
  2. delimiter 结尾标记 比如:delimiter $

存储过程的调用:

call 存储过程名(参数列表);

无参数存储过程

  • delimiter $
  • create procedure proc()

begin

insert into user(name,age,birthday) values ('小三',18,'2000-01-01');

insert into user(name,age,birthday) values ('小四',17,'1999-01-01');

insert into user(name,age,birthday) values ('小五',16,'1998-01-01');

insert into user(name,age,birthday) values ('小六',15,'1997-01-01');

  • 调用:call proc ()

测试:

输入如下命令

delimiter $

create procedure proc()

begin

insert into user(name,age,birthday) values ('小三',18,'2000-01-01');

insert into user(name,age,birthday) values ('小四',17,'1999-01-01');

insert into user(name,age,birthday) values ('小五',16,'1998-01-01');

insert into user(name,age,birthday) values ('小六',15,'1997-01-01');

end $

JDBC从入门到放弃-04:JDBC的callableStatement

可以看到存储过程已经建立ok

JDBC从入门到放弃-04:JDBC的callableStatement

使用存储过程

JDBC从入门到放弃-04:JDBC的callableStatement

结果正确

JDBC从入门到放弃-04:JDBC的callableStatement

带in参数模式的存储过程

案例:通过用户姓名查询对应的年龄和姓名

delimiter $

create procedure proc2(in in_name varchar(255))

begin

select u.name, u.age from user u

where u.name=in_name;

end $

JDBC从入门到放弃-04:JDBC的callableStatement

调用:call proc2('张三') 结果为

JDBC从入门到放弃-04:JDBC的callableStatement

带out参数模式的存储过程

简单示例

create procedure getnamebyid(in in_id int,out return_name char(255))

Select name into return_name from user where _id =in_id;

 

使用和结果

delimiter $

call getnamebyid(5,@name)$

select @name $

JDBC从入门到放弃-04:JDBC的callableStatement

带Iinout参数模式的存储过程

delimiter $

create procedure proc3(inout a int , inout b int)

begin

set a=a*2;

set b=b*2;

end $

调用:

delimiter $

set @a=10$

set @b=20$

call myp5(@a,@b)$

select @a,@b $

JDBC从入门到放弃-04:JDBC的callableStatement

删除存储过程:

drop procedure 存储过程名;

JDBC使用存储过程

我们已经在SQL中创建和使用了存储过程,现在我们尝试在JDBC中的使用。也就是callableStatement的使用。

其使用方式和preparedStatement类似。

  1. 无参存储过程

          /**

      * 测试存储过程(无参数)

      */

     //   delimiter $

     //   create procedure proc()

     //   begin

     //   insert into user(name,age,birthday) values ('小三',18,'2000-01-01');

     //   insert into user(name,age,birthday) values ('小四',17,'1999-01-01');

     //   insert into user(name,age,birthday) values ('小五',16,'1998-01-01');

     //   insert into user(name,age,birthday) values ('小六',15,'1997-01-01');

     //   end $

     //   call proc()

     @Test

     public void testStoredProcedure1() {

          Connection con = null;

          CallableStatement cs = null;

          ResultSet rs = null;

          try {

               con = DBUtils.getConnection();

               cs = con.prepareCall("{call proc()}");

               rs = cs.executeQuery();

          } catch (Exception e) {

               // TODO: handle exception

          } finally {

               DBUtils.close(con, cs, rs);

          }

     }

结果,已经插入正确

JDBC从入门到放弃-04:JDBC的callableStatement

  1. In存储过程

    /**

      * 测试存储过程(有参数)

      */

     // delimiter $

     // create procedure proc2(in in_name varchar(255))

     // begin

     // select u.name, u.age from user u

     // where u.name=in_name;

     // end $

     // call proc2('张三')

     @Test

     public void testStoredProcedure2() {

          Connection con = null;

          CallableStatement cs = null;

          ResultSet rs = null;

          try {

               con = DBUtils.getConnection();

               cs = con.prepareCall("{call proc2(?)}");

               cs.setString(1, "张三");

               rs = cs.executeQuery();

               while (rs.next()) {

                    String name = rs.getString("name");

                    int age= rs.getInt("age");

                    System.out.println("name = "+ name + " age = " + age);

               }

          } catch (Exception e) {

               // TODO: handle exception

          } finally {

               DBUtils.close(con, cs, rs);

          }

     }

为了测试循环,我们再往数据库中增加一条张三的记录:

数据库记录现在为:

JDBC从入门到放弃-04:JDBC的callableStatement

测试运行结果为,结果正确

JDBC从入门到放弃-04:JDBC的callableStatement

  1. In和out存储过程

     /**

      * 测试存储过程(有参数和有返回值)

      */

     //   create procedure getnamebyid(in in_id int,out return_name char(255))

     //   Select name into return_name from user where _id =in_id;

     @Test

     public void testStoredProcedure3() {

          Connection con = null;

          CallableStatement cs = null;

          ResultSet rs = null;

          try {

               con = DBUtils.getConnection();

               cs = con.prepareCall("{call getnamebyid(?,?)}");

               cs.setInt(1, 5);//索引为1,数据库中的id5

               //输出参数的话需要注册

               cs.registerOutParameter(2, Types.CHAR);

               //注册后需要更新

               cs.execute();

               String returnName = cs.getString("return_name");//cs.getString(2);

               cs.executeQuery();

               System.out.println("return_name = "+ returnName  );

          } catch (Exception e) {

               // TODO: handle exception

          } finally {

               DBUtils.close(con, cs, rs);

          }

     }

执行结果正确

JDBC从入门到放弃-04:JDBC的callableStatement

至此,关于JDBC的数据库操作相关类已讲解完毕。

附:用到的sql查询过程的SQL语句如下:

delimiter $

create procedure proc()

begin

insert into user(name,age,birthday) values ('小三',18,'2000-01-01');

insert into user(name,age,birthday) values ('小四',17,'1999-01-01');

insert into user(name,age,birthday) values ('小五',16,'1998-01-01');

insert into user(name,age,birthday) values ('小六',15,'1997-01-01');

end $

 

call proc()

 

 

delimiter $

create procedure proc2(in in_name varchar(255))

begin

select u.name, u.age from user u

where u.name=in_name;

end $

 

call proc2('张三')

 

create procedure getnamebyid(in in_id int,out return_name varchar(255)) Select name into return_name from user where _id =in_id;

 

delimiter $

call getnamebyid(5,@name)$

select @name $

 

 

delimiter $

create procedure proc3(inout a int , inout b int)

begin

set a=a*2;

set b=b*2;

end $

 

delimiter $

set @a=10$

set @b=20$

call proc3(@a,@b)$

select @a,@b $