存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。存储过程是数据库中的一个重要对象,任何一个设计良好的数据库应用程序都应该用到存储过程。在实际项目中只有高并发的情况下才考虑调用存储过程,因为存储过程在数据库调用前就已经编译好了,高频率地调用就能大大提高效率并且缩短程序的执行时间。然而对于一般的低频率进行数据库读写项目来说就没有必要时用存储过程了。
1.首先创建一个关系表
create table people(
id varchar(10) primary key,
name varchar(20) not null,
age int not null
);
insert into people values ('2012013251','刘永浪',21);
insert into people values ('2012013252','李云龙',22);
insert into people values ('2012013460','丁丽娟',20);
2.编写存储过程
delimiter $$
create procedure add_age(in new_id varchar(10),out new_name varchar(20))
begin
update people set age = age + 1 where id = new_id;
select name into new_name from people where id = new_id;
select id,name,age from people where id = new_id;
end $$
delimiter ;
上面的存储过程实现的是将指定id的人的age加1并且将name保存到输出参数,最后返回表中所有数据集合。
在JDBC技术中使用存储过程必须用到CallableStatement类。CallableStatement 对象为所有的 DBMS 提供了一种以标准形式调用已储存过程的方法。已储存过程储存在数据库中。对已储存过程的调用是 CallableStatement 对象所含的内容。这种调用是用一种换码语法来写的,有两种形式:一种形式带结果参数,另一种形式不带结果参数。结果参数是一种输出 (OUT) 参数,是已储存过程的返回值。两种形式都可带有数量可变的输入(IN 参数)、输出(OUT 参数)或输入和输出(INOUT 参数)的参数。问号将用作参数的占位符。在Java中要使用该类的registerOutParameter()方法注册输出参数。如果存储过程自身会返回结果集则需要用ResultSet来接受。
在Java中调用存储过程的语法是{call 过程名[(?,?...)]}
3.JDBC中调用存储过程
package cn.nwsuaf.jdbc;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
public class Procedure {
// 用于连接数据库对象
private Connection conn = null;
// 执行存储过程对象
private CallableStatement cs = null;
// 接受查询结果对象
private ResultSet rs = null;
// 数据库的路径
private final static String URL = "jdbc:mysql://localhost:3306/test";
// 构造方法,加载驱动程序并且连接数据库
public Procedure() {
try {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(URL, "root", "root");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 将指定id的人的age加1并且将name保存到输出参数,最后返回表中所有数据集合。
public void addAge(String num) {
// 调用存储过程的SQL语句
String sql = "{call add_age(?,?,?)}";
try {
// 执行操作
cs = conn.prepareCall(sql);
// 设置第一个输入参数
cs.setString(1, num);
// 注册第二个输出参数
cs.registerOutParameter(2, Types.INTEGER);
// 注册第三个输出参数
cs.registerOutParameter(3, Types.VARCHAR);
boolean b = cs.execute();// 执行
System.out.println("操作成功!" + cs.getString(3) + "的age已经由"
+ cs.getInt(2) + "增加到" + (cs.getInt(2) + 1));
// 获取存储过程的返回结果集
while (b) {
rs = cs.getResultSet();
while (rs.next()) {
String id = rs.getString(1);
String name = rs.getString(2);
int age = rs.getInt(3);
System.out.println("id=" + id + ",name=" + name + ",age="
+ age);
}
// 获取更多的结果集
b = cs.getMoreResults();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
conn.close();
cs.close();
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Procedure test = new Procedure();
test.addAge("2012013251");
}
}
运行结果为: