本篇讲述如何使用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调用数据库的存储过程的更多相关文章

  1. Mybatis调用数据库的存储过程和方法

     转载. https://blog.csdn.net/ml0228123/article/details/81002258   上次的项目,要求我用java代码调用存储过程,折腾了好久.最后总算成功了 ...

  2. Hibernate的调用数据库的存储过程

    Hibernate并没有给出直接调用数据库的存储过程的API,所以咋们就要通过调用原生的的connection对象来实现对存储过程的条用 Hibernate调用存储过程的步骤: 1:获得原生conne ...

  3. Java的jdbc调用SQL Server存储过程Bug201906131119

    SQL Server数据库存储过程,一个查询使用动态sql,另一个不使用动态sql,这种情况,jdbc可能获取不到实际查询数据,虽然数据库中执行没问题. 解决方法,都使用静态sql,或都使用动态sql ...

  4. Java的jdbc调用SQL Server存储过程Bug201906131120

    如果要查询结果,第一行使用set nocount on;可能可以解决问题.

  5. Java数据库连接——JDBC调用存储过程,事务管理和高级应用

    一.JDBC常用的API深入详解及存储过程的调用 相关链接:Jdbc调用存储过程 1.存储过程(Stored Procedure)的介绍 我们常用的操作数据库语言SQL语句在执行的时候需要先编译,然后 ...

  6. Java数据库连接--JDBC调用存储过程,事务管理和高级应用

    相关链接:Jdbc调用存储过程 一.JDBC常用的API深入详解及存储过程的调用 1.存储过程的介绍 我们常用的操作数据库语言SQL语句在执行的时候要先进行编译,然后执行,而存储过程是在大型数据库系统 ...

  7. JDBC调用存储过程的例子

    下面是我学到了Oracle存储过程,在这里跟大家简单的分享一下利用JDBC调用存储过程的例子: 废话就不啰嗦,现在就直接上机代码. 首先我利用的是Oracle中默认的 scott 数据库里的 emp员 ...

  8. jdbc操作数据库

    JDBC全称为:Java DataBase Connectivity(java数据库连接). SUN公司为了简化.统一对数据库的操作,定义了一套Java操作数据库的规范,称之为JDBC. 学习JD ...

  9. 使用 JDBC 调用函数 & 存储过程

    /** * 如何使用 JDBC 调用存储在数据库中的函数或存储过程 */ @Test public void testCallableStatment() { Connection connectio ...

随机推荐

  1. C语言,单链表操作(增删改查)(version 0.1)

    这天要面试,提前把链表操作重新写了一遍.备份一下,以备不时之需. 希望有人能看到这篇代码,并指正. // File Name : list.h #include "stdafx.h" ...

  2. UVa401 Palindromes

    #include <stdio.h>#include <string.h> char mirror(char c){    static const char m[] = &q ...

  3. instanceof 变量是否属于某一类 class 的实例

    <?phpclass MyClass{} class NotMyClass{}$a = new MyClass;$b = new NotMyClass;var_dump($a instanceo ...

  4. Tcl语言笔记之二

    1,表达式 1.1 操作数 TCL表达式的操作数通常是整数或实数.整数一般是十进制的, 但如果整数的第一个字符是0(zero),那么TCL将把这个整数看作八进制的,如果前两个字符是0x则这个整数被看作 ...

  5. 【转】Visual Stdio VS 错误 error : 0xC00000FD: Stack overflow. 更改堆栈空间解决栈溢出问题

    原文见:http://www.cnblogs.com/xiangwengao/archive/2012/03/16/2399888.html 问题 给一个程序添加小功能,在debug下能正常运行,在r ...

  6. struts2总结【转载】

    1,struts2的form表单里面和url里面的传值以及Action所继承的父类都可以自动set属性注入action中,及继承的action中. 2,凡是url和form表单传值,在action方法 ...

  7. [蘑菇街] 搜索、算法团队招募牛人啦-年底了走过路过不要错过 - V2EX

    [蘑菇街] 搜索.算法团队招募牛人啦-年底了走过路过不要错过 - V2EX [蘑菇街] 搜索.算法团队招募牛人啦-年底了走过路过不要错过

  8. android Bitmap围绕一个点进行旋转

    在项目中需要使用定位功能,也就是一个点围绕一个圆心进行旋转,查看了canvas的函数也就只有一个 canvas.drawBitmap(bitmap, matrix, paint)通过使用Matrix来 ...

  9. WebView使用详解

    一.用WebView处理页面导航 可以加载本地资源也可以加载web资源,区别是我们要加载本地资源要实现在assets文件夹里添加一个.html资源.调取网页的时候可以用loadUrl方法把网址添加进去 ...

  10. PHP - 多文件上传

    <html> <head> <meta charset="utf-8"> <title>index_uploads</titl ...