JDBC从入门到放弃-04:JDBC的callableStatement
JDBC从入门到放弃
04-JDBC的callableStatement
第一节我们看到JDBC支持的数据库操作除了statement和preparedSatement以外还支持callableStatement。上面两节讲解了statement和preparedStatement的内容,这节我们继续讲解callableStatement的内容,也就是所谓的存储过程。
什么是存储过程
SQL中的存储过程类似于java中的函数(方法)。
存储过程:预先编辑好SQL语句的集合,这个集合完成了某项具体的功能集合,我需要这个功能的时候,只要调用这个过程就好了!(一般大型的企业项目才会用到,中小型的项目不会使用到,这里作为了解即可)
创建语法
create procedure 存储过程的名字(参数列表)
begin
存储过程体(SQL语句的集合);
end
注意:
- 参数列表包含三个部分:参数模式 参数名 参数类型
(比如: in s_name varchar(20) )
参数模式:
in : 该参数可以作为输入,需要调用方传入值来给存储过程
out : 该参数可以作为输出,该参数可以作为返回值给调用方
inout : 该参数既可以做输入,也可以作为输出
- 如果存储体只要一句SQL语句,begin和end可以省略,存储体里的slq语句结尾处必须加分号,避免数据库误判为存储过程的结束标记,所以需要我们自定义命令的结尾符号:
- 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 $ |
可以看到存储过程已经建立ok
使用存储过程
结果正确
带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('张三') 结果为
带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 $
带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 $
附
删除存储过程:
drop procedure 存储过程名;
JDBC使用存储过程
我们已经在SQL中创建和使用了存储过程,现在我们尝试在JDBC中的使用。也就是callableStatement的使用。
其使用方式和preparedStatement类似。
- 无参存储过程
/** * 测试存储过程(无参数) */ // 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); } } |
结果,已经插入正确
- 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); } } |
为了测试循环,我们再往数据库中增加一条张三的记录:
数据库记录现在为:
测试运行结果为,结果正确
- 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,数据库中的id为5 //输出参数的话需要注册 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的数据库操作相关类已讲解完毕。
附:用到的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 $