package cn.hncu.jdbc;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import org.junit.Test;
import cn.hncu.pub.ConnUtils;
/*
* 演示Java中如何调用数据库中的存储过程
*
* 调用存储过程得用CallableStatement,
* 它和PreparedStatement类似,也是Statement的子类,也可把用户输入用参数封装的方式防黑。
* 即在父类的基础上增加了一些功能。
*
*/
public class CallableDemo {
// 无参, 如 call p1();
@Test
public void demo1() throws Exception {
Connection con = ConnUtils.getConn();
// ※※※调用存储过程得用 CallableStatement语句对象
CallableStatement cs = con.prepareCall("call p1()");
ResultSet rs = cs.executeQuery(); // 如果存储过程调用之后会有返回结果,则最好用executeQuery()
while (rs.next()) {
System.out.println(rs.getString("name"));
}
con.close();
}
// 有输入参, 如 call p2('P011','小五',28);
@Test
public void demo2() throws Exception {
Connection con = ConnUtils.getConn();
// CallableStatement cs = con.prepareCall("call p2('P011','小五',28)");
// //sql写死了
CallableStatement cs = con.prepareCall("call p2(?,?,?)"); // sql写活
cs.setString(1, "P201");
cs.setString(2, "大王");
cs.setInt(3, 45);
ResultSet rs = cs.executeQuery(); // 如果存储过程调用之后会有返回结果,则最好用executeQuery()
while (rs.next()) {
System.out.println(rs.getString("name"));
}
con.close();
}
// 有输入参和返回值, 如 CALL p3('P012','小小五',27, @aa);
@Test
public void demo3() throws Exception {
Connection con = ConnUtils.getConn();
CallableStatement cs = con.prepareCall("call p3(?,?,?,?)"); // 最后一个?号是用于输出参数的
//3个输入参数
cs.setString(1, "P202");
cs.setString(2, "大大王");
cs.setInt(3, 55);
//※※注册一个返回类型的参数
cs.registerOutParameter(4, Types.INTEGER); //把第4个问号注册成输出参数
//cs.execute(), cs.executeUpdate()
ResultSet rs = cs.executeQuery(); // 如果存储过程调用之后会有返回结果,则最好用executeQuery()
while (rs.next()) {
System.out.println(rs.getString("name"));
}
//※※
int n = cs.getInt(4); //获取存储过程的返回值,之前已经把它注册到第4个点位符了
System.out.println("n="+n);
con.close();
}
}