* [3)执行有参有返回](#3_122)
* [4)执行存储函数](#4_199)
* [5)其他情况](#5_252)
19【CallableStatement 接口】
1.1 CallableStatement 接口
1.1.1 CallableStatement 简介
CallableStatement是PreparedStatement的子类,主要是调用数据库中的存储过程/存储函数。并通过CallableStatement对象可以获取存储过程/存储函数的执行结果;
1.1.2 CallableStatement的使用
1)执行无参无返回
- 测试数据准备:
-- 创建一张测试表
create table test(
id int primary key auto\_increment,
name varchar(200)
);
-- 创建一个无参无返回的存储过程
create procedure test1()
begin
insert into test values(null,uuid());
end;
- 测试代码:
package com.dfbz.demo;
import com.dfbz.utils.JdbcUtils;
import org.junit.Test;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.SQLException;
/\*\*
\* @author lscl
\* @version 1.0
\* @intro: 执行存储过程
\*/
public class Demo14\_CallableStatement {
/\*\*
\* 执行无参无返回
\* @throws SQLException
\*/
@Test
public void test1() throws SQLException {
// 获取数据库连接
Connection connection = JdbcUtils.getConnection();
// 定义存储过程
CallableStatement cs = connection.prepareCall("call test1()");
// 执行存储过程
cs.execute();
JdbcUtils.close(connection, cs);
}
}
2)执行有参无返回
- 定义存储过程:
CREATE PROCEDURE test2 (in id int,in name varchar(30))
begin
insert into test values(id,name);
end ;
- 测试代码:
/\*\*
\* 执行有参无返回
\* @throws SQLException
\*/
@Test
public void test2() throws SQLException {
// 获取数据库连接
Connection connection = JdbcUtils.getConnection();
// 定义存储过程
CallableStatement cs = connection.prepareCall("call test2(?,?)");
cs.setInt(1,10);
cs.setString(2,"zhangsan");
// 执行存储过程
cs.execute();
JdbcUtils.close(connection, cs);
}
3)执行有参有返回
- 定义存储过程:
CREATE PROCEDURE test3 (in id int,out str1 varchar(30),out str2 varchar(30))
begin
if id=1 then
set str1 = "Java";
set str2 = "薪资12k";
elseif id=2 then
set str1 = "UI";
set str2 = "薪资8k";
elseif id=3 then
set str1 = "产品";
set str2 = "薪资10k";
end if;
end;
call test3(2,@str1,@str2);
select @str1;
select @str2;
- 测试代码:
/\*\*
\* 执行有参有返回
\* @throws SQLException
\*/
@Test
public void test3() throws SQLException {
// 获取数据库连接
Connection connection = JdbcUtils.getConnection();
// 定义存储过程
CallableStatement cs = connection.prepareCall("call test3(?,?,?)");
// 输入参数
cs.setInt(1,2);
// 输出参数
cs.registerOutParameter(2, Types.VARBINARY);
cs.registerOutParameter(3, Types.VARBINARY);
// 执行存储过程
cs.execute();
// 根据参数名获取值
String str1 = cs.getString("str1");
String str2 = cs.getString("str2");
System.out.println(str1);
System.out.println(str2);
System.out.println("-----------------");
// 根据参数索引获取
str1 = cs.getString(2);
str2 = cs.getString(3);
System.out.println(str1);
System.out.println(str2);
System.out.println(str1);
System.out.println(str2);
JdbcUtils.close(connection, cs);
}
4)执行存储函数
存储函数必须有返回值,JDBC执行存储函数就相当于执行存储过程时多了一个输出参数而已;
- 定义存储函数:
-- 定义存储函数
create function test4(num int)
returns int
begin
return num;
end;
-- 执行存储函数
select test4(10);
- 测试代码:
/\*\*
\* 执行存储函数
\*
\* @throws SQLException
\*/
@Test
public void test4() throws SQLException {
// 获取数据库连接
Connection connection = JdbcUtils.getConnection();
// 定义存储过程
CallableStatement cs = connection.prepareCall("{?=call test4(?)}");
// 注册输出参数(存储函数的结果集)
cs.registerOutParameter(1,Types.INTEGER);
// 输入参数
cs.setInt(2, 100);
// 执行存储函数
cs.execute();
// 获取第一个占位符的值
int result = cs.getInt(1);
System.out.println(result);
JdbcUtils.close(connection, cs);
}
5)其他情况
有的时候执行存储过程时,其内部会产生结果集,该结果集并没有当做参数返回出来,JDBC也支持获取这部分的结果集;
- 定义存储过程:
CREATE PROCEDURE test5 (out str varchar(30))
begin
select \* from test;
set str = "success";
end;
call test5(@str)
select @str;
- 测试代码:
/\*\*
\* 执行存储函数
\*
\* @throws SQLException
\*/
@Test