使用JDBC调用数据库的存储过程
本篇讲述如何使用JDBC来调用MySQL数据库中的存储过程。建议在学习如何使用JDBC调用存储过程前,请先了解如何在数据库中使用存储过程。
存储过程是指在数据库系统中,一组为了完成特定功能的SQL语句集,存储在数据库中,经过第一次编译后以后再调用任意次都不需要重新编译了。说白了就是一堆SQL语句的合并,中间加了点逻辑控制,俗称为数据库中的函数。在一些金融等大型企业中,基本都是由内部人员编写好存储过程,然后由外部程序员调用存储过程,因为内部数据逻辑处理方式涉及商业机密等等。
也就是说我们现在有两种方式来处理数据库中的数据,一是通过JDBC从数据库中取出数据然后通过业务层编写处理数据的逻辑代码;二是在数据库中定义数据的存储过程,在这个存储过程中完成对数据的逻辑操作,就好比数据库中的函数,而我们在Java程序中只要调用数据库中的这个存储过程即可。
操作:
在MySQL数据库中确定要调用哪个存储过程,包括确定该存储过程的参数列表为哪些SQL类型。
在JDBC中通过链接Connection对象,调用prepareCall(…)方法,在prepareCall方法中的参数为字符串,内容应该为”{call 存储过程名(?(占位符,个数根据存储过程参数来定)...)}”,调用这个方法后返回CallableStatement对象。
通过返回的CallableStatement对象对于传入类型的参数(IN),如PreparedStatement对象一样设置占位符的替代参数,而对于占位符对应的参数是输出类型(INOUT),则调用CallableStatement对象的registerOutParameter(…)方法,该方法第一个参数指明替代第几个占位符,第二个参数指明该存储过程的输出参数在数据库中的SQL类型,在Java程序中可以使用Types类的字段指定。
最后通过CallableStatement对象的execute()方法执行存储过程,即可通过getXXX方法获取prepareCall方法参数中占位符类型为输出的参数值。
下面通过一个例子来说明。
例:
我们现在数据库中自定义一个存储过程,这个存储过程的功能是在我们传入的每一个字符串参数面前加上一段字符串,即将两端字符串连接,最后返回:
delimiter // create procedure addPrefix(in inputParam varchar(255),inout inOutParam varchar(255)) begin
select concat('long live sd...',inputParam) into inOutParam;
end // delimiter ;
分析:第一行我们将MySQL中的分隔符先定义为“//”,因为等会在存储过程的逻辑代码中会使用到“;”,不先定义别的分隔符的话逻辑代码还没写完数据库就执行了。第二行定义存储过程的名称,同时在参数列表中定义参数输入输出类型(IN,OUT,INOUT),参数名称,参数类型(SQL数据类型)。第三行开始以关键字“BEGIN”开始,以“END”和刚才定义的分隔符结束,在这两个中间就是平常的SQL语句了,也就是在这个部分编写我们处理参数的逻辑。最后,我们将MySQL数据库的分隔符重新定义回分号“;”。

注:在数据库中定义存储过程时,应先选择使用的库,这里我使用jdbcdemo库。
这里顺便一说在MySQL中如何使用SQL命令来调用存储过程,对于我们上面刚刚创建的存储过程,可以使用如下SQL命令语句来调用和查看结果:
set @inputParam = 'LRR';
call addPrefix(@inputParam,@result);
select @result;
因为我们使用到了输入参数,因此在调用存储过程之前需要先设置好输入类型In的参数,在MySQL中,使用“@”代表该参数是一个用户变量,而对于输出类型out或inout也需要一个自定义用户变量,最后由select将结果显示,结果如下图所示:

(注:用户变量在退出MySQL命令行窗口后会自动释放资源)
下面开始介绍在Java中如何调用数据库中的存储过程。
创建Java工程,在工程中导入数据库连接驱动的jar包。在【src】目录下新建一个database.properties文件,内容如下:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdemo
username=root
password=root
构建JDBC的工具类,包括注册驱动,获取连接,释放资源和连接等,这部分同《JDBC操作数据库的学习(2)》中相同,此处略。
接着,我们将使用JDBC来调用上面刚刚定义的存储过程:
public void callableTest() throws SQLException {
Connection conn = null;
CallableStatement st = null;
ResultSet rs = null;
try{
conn = JdbcUtils.getConnection();
st = conn.prepareCall("{call addPrefix(?,?)}");
st.setString(1, "love LRR");
st.registerOutParameter(2, Types.VARCHAR);
st.execute();
String contactPrefix = st.getString(2);
System.out.println(contactPrefix);
}finally{
JdbcUtils.release(conn, st, rs);
}
}
观察程序运行结果:

CallableStatement对象是Statement对象的子类,因此在调用JdbcUtils.release方法时使用了多态。在prepareCall方法中的参数是指定调用哪个存储过程的字符串,同时使用到了占位符,那么通过CallableStatement对象对传入类型的参数设置要替代占位符的数据,而对于输出类型的参数则调用registerOutParameter方法替代占位符并指定SQL类型。在Java中Types类封装了各种SQL类型的字段。
以上就是如何使用JDBC调用MySQL数据库中的存储过程的步骤。
使用JDBC调用数据库的存储过程的更多相关文章
- Mybatis调用数据库的存储过程和方法
转载. https://blog.csdn.net/ml0228123/article/details/81002258 上次的项目,要求我用java代码调用存储过程,折腾了好久.最后总算成功了 ...
- Hibernate的调用数据库的存储过程
Hibernate并没有给出直接调用数据库的存储过程的API,所以咋们就要通过调用原生的的connection对象来实现对存储过程的条用 Hibernate调用存储过程的步骤: 1:获得原生conne ...
- Java的jdbc调用SQL Server存储过程Bug201906131119
SQL Server数据库存储过程,一个查询使用动态sql,另一个不使用动态sql,这种情况,jdbc可能获取不到实际查询数据,虽然数据库中执行没问题. 解决方法,都使用静态sql,或都使用动态sql ...
- Java的jdbc调用SQL Server存储过程Bug201906131120
如果要查询结果,第一行使用set nocount on;可能可以解决问题.
- Java数据库连接——JDBC调用存储过程,事务管理和高级应用
一.JDBC常用的API深入详解及存储过程的调用 相关链接:Jdbc调用存储过程 1.存储过程(Stored Procedure)的介绍 我们常用的操作数据库语言SQL语句在执行的时候需要先编译,然后 ...
- Java数据库连接--JDBC调用存储过程,事务管理和高级应用
相关链接:Jdbc调用存储过程 一.JDBC常用的API深入详解及存储过程的调用 1.存储过程的介绍 我们常用的操作数据库语言SQL语句在执行的时候要先进行编译,然后执行,而存储过程是在大型数据库系统 ...
- JDBC调用存储过程的例子
下面是我学到了Oracle存储过程,在这里跟大家简单的分享一下利用JDBC调用存储过程的例子: 废话就不啰嗦,现在就直接上机代码. 首先我利用的是Oracle中默认的 scott 数据库里的 emp员 ...
- jdbc操作数据库
JDBC全称为:Java DataBase Connectivity(java数据库连接). SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC. 学习JD ...
- 使用 JDBC 调用函数 & 存储过程
/** * 如何使用 JDBC 调用存储在数据库中的函数或存储过程 */ @Test public void testCallableStatment() { Connection connectio ...
随机推荐
- [Swust OJ 567]--老虎在不在笼子里(凸包问题)
题目链接:http://acm.swust.edu.cn/problem/567/ Time limit(ms): 1000 Memory limit(kb): 65535 一只老虎自从看了< ...
- [置顶] Linux下文件和目录权限说明
在Linux下使用ls -l或者ll命令可以查看文件和文件夹的权限.结果显示类似于: drwxrwxrwx,这里分为四组,分别为文件类型,文件所有者的权限(读写执行),文件所有者所在组用户的权限(读写 ...
- ELK 之三:Kibana 使用与Tomcat、Nginx 日志格式处理
一:kibana安装: kibana主要是搜索elasticsearch的数据,并进行数据可视化的展现,新版使用nodejs. 1.下载地址: https://www.elastic.co/downl ...
- QT 静态编译后中文可能会出现乱码
QT 静态编译后中文可能会出现乱码.这是因为处理文字编码的 libqcncodecs 库是以 plugin 形式存放在 QT 静态编译目录/plugs/codecs/libqcncodecs.a 文件 ...
- 设置QPushButton的平面与突出(遍历控件)
#include "ui_maindialog.h" #include "maindialog.h" #include <QState> #incl ...
- ASP.NET MVC 5 学习教程:添加视图
原文 ASP.NET MVC 5 学习教程:添加视图 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 通过控 ...
- Computer Transformation(规律,大数打表)
Computer Transformation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/ ...
- Eclispse 换主题、皮肤、配色,换黑色主题护眼
链接地址:http://jingyan.baidu.com/article/6c67b1d68c03be2787bb1ed6.html Eclipse写android代码时,默认的文本和框架都是白色, ...
- C# 使用IENUMERABLE,YIELD
C# 使用IENUMERABLE,YIELD 前言 在上篇文章中我得出结论,遍历迭代器修改迭代器中项目的值未生效,是因为使用了yield return,并且每次遍历迭代器都执行返回迭代器的方法.这篇文 ...
- C# 仿金山毒霸启动和关闭淡入淡出效果
原文 C# 仿金山毒霸启动和关闭淡入淡出效果 01 #region 窗体关闭效果 02 03 #region 私有方法 04 [DllImportAttribute("user32.dl ...