Java中执行存储过程.docx
《Java中执行存储过程.docx》由会员分享,可在线阅读,更多相关《Java中执行存储过程.docx(10页珍藏版)》请在冰豆网上搜索。
![Java中执行存储过程.docx](https://file1.bdocx.com/fileroot1/2023-6/5/64566137-acec-40d9-9edb-54746ea87719/64566137-acec-40d9-9edb-54746ea877191.gif)
Java中执行存储过程
Java执行存储过程常用方法
首先说一下存储过程的优点:
1.存储过程是预编译的,第一次编译执行后,之后的执行效率会比较,也就是存储过程效率高
2.存储过程,只是提供给用户使用,封装了内部操作,可以防止注入攻击
3.便于修改和维护,只需要修改存储过程内部业务实现,并不需要修改使用的实现.
4.减少使用流量,存储过程内部sql语句,是储存在数据库中,所以省去了加载sql语句的流量
存储过程的形式大概可以分为以下几种:
1.无参无返2.有参无返3.无参有返4有参有返5.传出参数
这里的返回值并不是指执行查询之后返回的结果视图,而是值在存储过程中return返回的值..下面将对SqlServer数据库使用存储过程举例:
准备工作:
1.使用JDBC链接方式,需要引入jar包:
sqljdbc4.jar,封装一个数据连接类,方便接下来的操作,这里类名为DBHelper,定义了一个静态方法getCon(),用于返回链接对象,返回值类型为Connection,还有一个关闭对象的方法closeAll(Connectionco,Statementps,ResultSetrs);其中参数分别为Connection,Statement,ResultSet的对象。
具体代码如下:
publicclassDBHelper{
privatestaticfinalStringdriver="com.microsoft.sqlserver.jdbc.SQLServerDriver";
privatestaticfinalStringurl="jdbc:
sqlserver:
//127.0.0.1:
1433;DataBaseName=demo";
privatestaticfinalStringsa="sa";
privatestaticfinalStringpwd="123";
//建立连接
publicstaticConnectiongetCon(){
Connectionco=null;
try{
Class.forName(driver);
co=DriverManager.getConnection(url,sa,pwd);
}catch(Exceptione){
e.printStackTrace();
System.out.println(e.getMessage());
}
returnco;
}
//关闭所有对象
publicstaticvoidcloseAll(Connectionco,Statementps,ResultSetrs){
try{
if(rs!
=null){
ps.close();
rs=null;
}
if(ps!
=null){
ps.close();
ps=null;
}
if(co!
=null){
co.close();
co=null;
}
}catch(Exceptione){
System.out.println(e.getMessage());
}
}
}
注意:
这里的关闭方法参数中的Statementps,如果接下来操作会使用PreparedStatement和CallableStatement接口,不需要进行类型转化,因为后两者本身就已经直接或间接实现了Statement接口,有疑问具体可以查阅一下API文档。
2.这里作为示例,准备了一个demo数据库(sqlserver),里面有一张studentInfo表,添加5条测试数据,表结构如下:
createtablestudentInfo
(
stuIdintprimarykeyidentity(1,1),
stuNamevarchar(20)notnull,
stuAgeintnotnulldefault0,
)
OK,所有的准备工作已经完成。
接下来讲示例几种存储过程的示例:
1.无参无返:
创建存储过程proc_getAllInfo如下:
--查询所有studentInfo记录
createprocproc_getAllInfo
as
begin
select*fromstudentInfo
end
在java中,执行普通的sql语句,使用的是Statement对象或者PreparedStatement,而在调用存储过程,应该使用CallableStatement接口。
CallableStatement接口:
用于执行SQL存储过程的接口。
JDBCAPI提供了一个存储过程SQL转义语法,该语法允许对所有RDBMS使用标准方式调用存储过程。
执行上面的存储过程示例代码:
//测试类
publicclassTest{
publicstaticvoidmain(String[]args)throwsException{
Connectionco=DBHelper.getCon();//获取链接对象
CallableStatementcs=co.prepareCall("{callproc_getAllInfo}");//通过连接获取CallableStatement对象
ResultSetrs=cs.executeQuery();//执行并返回结果集
while(rs.next()){//循环读取逐行
System.out.print(rs.getString
(2)+"");
}
DBHelper.closeAll(co,cs,rs);
}
}
1.通过已经封装之后的DBHelper类中的getCon()静态方法获取连接对象Co
2.通过co对象的prepareCall(Stringarg0)方法可以换回一个指定存储过程的调用对象,需要注意的是,参数arg0在次应该写为“{call存储过程名}”。
即:
CallableStatementcs=co.prepareCall("{callproc_getAllInfo}");
3.通过使用cs的executeQuery();返回执行的结果集,为ResultSet类型,因为CallablesStatement接口实现了PrepareStatement接口,而PrepareStatement接口又实现了Statement接口,所以CallablesStatement对象拥有executeQuery()方法。
4.然后使用将返回的结果集逐行读取。
5.最后,不要忘记关闭所有的对象。
还是调用DBHelper中的静态方法closeAll()。
接下来操做就不在解释上面这些语句,有特殊不同地方会有所标注,来看第二个示例:
2.有参无返:
创建存储过程proc_getInfoByStuName,有一个字符串类型参数,如下:
--根据stuName查询记录
createprocproc_getInfoByStuName
@stuNamevarchar(20)
as
begin
select*fromstudentInfowherestuName=@stuName
end
执行上面的存储过程示例代码:
//测试类
publicclassTest{
publicstaticvoidmain(String[]args)throwsException{
Connectionco=DBHelper.getCon();//获取链接对象
CallableStatementcs=co.prepareCall("{callproc_getInfoByStuName(?
)}");//通过连接获取CallableStatement对象
StringstuName="Tom";
cs.setString(1,stuName);
ResultSetrs=cs.executeQuery();//执行并返回结果集
while(rs.next()){//循环读取逐行
System.out.print(rs.getString
(2)+"");
}
DBHelper.closeAll(co,cs,rs);
}
}
执行之后,控制台会输出Tom
需要注意的是:
获取CallableStatement对象方法不变,需要更改的是co.prepareCall(Stringarg0)方法中的参数,更改为“{call存储过程名(?
)}“。
其中存储过程参数放在存储过程名字之后的()之中,?
指代参数,有几个参数就需要在()中添加几个?
.(这里字符串类型不需要加单引号),相当于占位符..然后需要使用cs.setObject(Objecto),根据参数类型调用相应的set方法...接下来一样,这里不多做解释…
3.无参有返:
创建无参有返的存储过程如下:
createprocproc_updateAge
as
begin
updatestudentInfosetstuAge=21wherestuAge=20
return100
end
执行上面的存储过程示例代码:
publicstaticvoidmain(String[]args)throwsException{
Connectionco=DBHelper.getCon();//获取链接对象
CallableStatementcs=co.prepareCall("{?
=callproc_updateAge}");//通过连接获取CallableStatement对象
cs.registerOutParameter(1,java.sql.Types.INTEGER);//注册参数为传出或者返回类型参数Int类型
cs.execute();//执行
intresult=cs.getInt
(1);//获取参数
DBHelper.closeAll(co,cs,null);
System.out.println(result);//输出
}
需要注意的是:
获取CallableStatement对象方法不变,需要更改的是co.prepareCall(Stringarg0)方法中的参数,更改为“{?
=call存储过程名}“.然后使用cs.registerOutParameter(intparamIndex,sqlType);方法注册参数,第一个参数为需要注册参数的下标(从1开始),第二个为注册的类型,不是java中的数据类型,而是sql的数据类型,可以使用java.sql.Types.类型方法类生命sql中的类型…获取返回值,在调用cs对象的执行方法之后,使用get方法即可接受到返回值.
控制台输出100
4.有参有返:
上面已经讲了有参无返,无参有返的调用方法,那么举一反三很简单就可以想到有参有返如何执行了,我还是写一下吧.
存储过程
createprocproc_deleteStuByName
@namevarchar(20)
as
begin
deletefromstudentInfowherestuName=@name
return100
end
java执行此存储过程:
//测试类
publicclassTest{
publicstaticvoidmain(String[]args)throwsException{
Connectionco=DBHelper.getCon();//获取链接对象
CallableStatementcs=co.prepareCall("{?
=callproc_deleteStuByName(?
)}");//通过连接获取CallableStatement对象
cs.registerOutParameter(1,java.sql.Types.INTEGER);//注册参数为传出或者返回类型参数Int类型
cs.setString(2,"Tom");
cs.execute();//执行
intresult=cs.getInt
(1);//获取参数
DBHelper.closeAll(co,cs,null);
System.out.println(result);//输出
}
}
关于实现过程,就不在解释,需要注意的是:
只有传出参数或者return才需要registerOutParameter()注册参数,其余的为普通参数,直接使用set方法就可为参数赋值,参数下标索引,从1开始,从左往右一次增长…
5.带有传出参数的存储过程:
看到这里,相信你已经基本上可以猜到如何使用带有传出参数的存储过程了,对的,就是使用registerOutParameter()方法
存储过程代码:
createprocproc_deleteStuByNameAndGetParam
@namevarchar(20),
@stuNamevarchar(20)output
as
begin
deletefromstudentInfowherestuName=@name
select@stuName=stuNamefromstudentInfowherestuId=1
end
java执行此存储过程:
//测试类
publicclassTest{
publicstaticvoidmain(String[]args)throwsException{
Connectionco=DBHelper.getCon();//获取链接对象
CallableStatementcs=co.prepareCall("{callproc_deleteStuByNameAndGetParam(?
?
)}");//通过连接获取CallableStatement对象
cs.setString(1,"Tom");
cs.registerOutParameter(2,java.sql.Types.VARCHAR);//注册参数为传出或者返回类型参数Int类型
cs.execute();//执行
Stringresult=cs.getString
(2);//获取参数
DBHelper.closeAll(co,cs,null);
System.out.println(result);//输出
}
}
关于实现过程,需要解释吗?
总结:
1.执行存储过程是使用CallableStatement接口的对象
2.使用Connection对象的prepareCall(“{call存储过程名(参数)}”)方法方法指定存储过程,并返回CallableStatement的一个对象.
3.参数下标从1开始,由左往右增长,可是使用?
方式声明参数,使用set方法给参数赋值
4.如果存储过程中有return或者传出参数时候,需要明确使用CallableStatement对象的registerOutParameter(参数下标,sql类型)注册参数.
”
最后.
祝大家学习愉快.
工作生活顺利!