JDBC对MySQL数据库存储过程的调用

Posted silentmuh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC对MySQL数据库存储过程的调用相关的知识,希望对你有一定的参考价值。

 一、MySQL数据库存储过程:

        1、什么是存储过程

        存储过程(英文:Stored Procedure)是在大型数据库系统中,为了完成特定功能而编写的一组的SQL语句集。存储过程经编译存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。

        2、与一般SQL语句相比,使用存储过程有哪些优点,有哪些缺点

        优点:
        1)、减少了脚本的执行环节,缩短了获取数据的时间。存储过程只在创建的时进行编译,在调用使用的时候直接执行,不需再次编译;而一般SQL语句每次执行前都需要编译一次,故效率没有存储过程高;
        2)、减少网络传输量,提高了传输速度。存储过程编译后存储在数据库服务器上,使用的时候只需要指定存储过程的名字并给出参数(如果该存储过程带有参数)就可以了;而一般SQL语句需要将所执行语句字符串传输到数据库服务器端,相比于存储过程而言向数据库服务端传送的字符串长度比较大;
        3)、安全性比较高。为存储过程参数赋值只能使用问号传参的形式(这一点可以通过下面JDBC对mysql数据库存储过程的调用例子体现出来),这样可以防止SQL注入式攻击;一般SQL语句也可以做到防止SQL注入式攻击,但是并不是必须的。可以将Grant、Deny以及Revoke权限应用于存储过程,即言可以设定只有某些用户才具有对指定存储过程的使用权;
        缺点:
        1)、如果在一个程序系统中大量的使用存储过程,当程序交付使用的时候随着客户需求的增加会导致数据结构的变化,接着就是存储过程的修改,这样系统维护就会越来越难并且代价也会越来越大。

        3、怎样创建存储过程及创建存储过程需要注意的地方

        存储过程的创建格式为:

        create procedure 存储过程名([[IN |OUT |INOUT ] 参数名 数据类形...])
        begin
        存储过程体
        end

        创建存储过程的具体例子见下面JDBC对mysql数据库存储过程的调用例子;

        需要注意的地方:见下面JDBC对MySQL数据库存储过程的调用例子内创建存储过程语句中的注释;

        二、JDBC对MySQL数据库存储过程的调用:

        为了更加直观的介绍JDBC如何实现对MySQL数据库存储过程的调用,这里直接以例子的形式展示。

        1、没有任何输入和输出参数的存储过程

1 drop PROCEDURE if EXISTS jdbcprocnoinandout;
2 create PROCEDURE jdbcprocnoinandout()
3 BEGIN
4     select * from test.test;
5 end;

下面是Java代码:

1 Connection connectionNoInAndOut = MyConnection.getConnection();
2         String jdbcprocNoInAndOut = "{call jdbcprocnoinandout()}";
3         CallableStatement csNoInAndOut = connectionNoInAndOut.prepareCall(jdbcprocNoInAndOut);
4         csNoInAndOut.execute();
5         ResultSet rsNoInAndOut = csNoInAndOut.getResultSet();
6         while (rsNoInAndOut.next()) {
7             System.out.println("jdbcprocnoinandout:"+rsNoInAndOut.getString("id")+"--------"+rsNoInAndOut.getString("value1"));
8         }
9         MyConnection.closeConnection(connectionNoInAndOut, csNoInAndOut, rsNoInAndOut);

2、只有两个输入参数的存储过程

1 drop PROCEDURE if EXISTS jdbcprocallin;
2 create PROCEDURE jdbcprocallin(id int, value1 VARCHAR(20))
3 BEGIN
4     insert into test.test values(id,value1);
5     select * from test.test;
6 end;

Java代码:

 1 Connection connectionAllIn = MyConnection.getConnection();
 2         String jdbcprocAllIn = "{call jdbcprocallin(?,?)}";
 3         CallableStatement csAllIn = connectionAllIn.prepareCall(jdbcprocAllIn);
 4         csAllIn.setInt(1, 1);
 5         csAllIn.setString(2, "asdf");
 6         csAllIn.execute();
 7         ResultSet rsAllIn = csAllIn.getResultSet();
 8         while (rsAllIn.next()) {
 9             System.out.println("jdbcprocallin:"+rsAllIn.getString("id")+"--------"+rsAllIn.getString("value1"));
10         }
11         MyConnection.closeConnection(connectionAllIn, csAllIn, rsAllIn);

3、一个输入参数一个输出参数的存储过程

1 drop PROCEDURE if EXISTS jdbcprocinandout;
2 create PROCEDURE jdbcprocinandout(in id VARCHAR(20), out value1 VARCHAR(20))
3 BEGIN
4     set value1 = CONCAT(我是:,id);
5     select value1;
6 end;

Java代码:

 1 Connection connectionInAndOut = MyConnection.getConnection();
 2         String jdbcprocInAndOut = "{call jdbcprocinandout(?,?)}";
 3         CallableStatement csInAndOut = connectionInAndOut.prepareCall(jdbcprocInAndOut);
 4         csInAndOut.setString(1, "123123");
 5         csInAndOut.registerOutParameter(2, Types.VARCHAR);
 6         csInAndOut.execute();
 7         ResultSet rsInAndOut = csInAndOut.getResultSet();
 8         while (rsInAndOut.next()) {
 9             System.out.println("jdbcprocinandout:"+csInAndOut.getString("value1"));
10         }
11         MyConnection.closeConnection(connectionInAndOut, csInAndOut, rsInAndOut);

4、两个输出参数的存储过程

1 drop PROCEDURE if EXISTS jdbcprocallout;
2 create PROCEDURE jdbcprocallout(out outid VARCHAR(20), out outvalue1 VARCHAR(20))
3 BEGIN
4     select * into outid,outvalue1 from test.test limit 1;
5     select outid,outvalue1 ;
6 end;

Java代码:

 1 Connection connectionAllOut = MyConnection.getConnection();
 2         String jdbcprocAllOut = "{call jdbcprocallout(?,?)}";
 3         CallableStatement csAllOut = connectionAllOut.prepareCall(jdbcprocAllOut);
 4         csAllOut.registerOutParameter(1, Types.VARCHAR);
 5         csAllOut.registerOutParameter(2, Types.VARCHAR);
 6         csAllOut.execute();
 7         ResultSet rsAllOut = csAllOut.getResultSet();
 8         while (rsAllOut.next()) {
 9             System.out.println("jdbcprocallout:"+csAllOut.getString("outid")+"--------"+csAllOut.getString("outvalue1"));
10         }
11         MyConnection.closeConnection(connectionAllOut, csAllOut, rsAllOut);

数据库中调用带有输出参数的存储过程写法,例如刚才两个带有输出参数的

1 call jdbcprocinandout(lily,@value1);
2 call jdbcprocallout(@vid,@vvalue);
-- 输出参数前面必须带“@”符号,变量名可以随便写一个合法变量都可以。

 

附上MyConnection类

 1 package net.lily.test;
 2 
 3 import java.sql.*;
 4 
 5 public class MyConnection {
 6     
 7     public static Connection getConnection() {
 8         Connection connection = null;
 9         String url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useOldAliasMetadataBehavior=true";
10         String user = "root";
11         String pwd = "123456";
12         String driverName = "com.mysql.jdbc.Driver";
13         try {
14             Class.forName(driverName);
15             connection = DriverManager.getConnection(url, user, pwd);
16         } catch (ClassNotFoundException e) {
17             e.printStackTrace();
18         } catch (SQLException e) {
19             e.printStackTrace();
20         }
21         return connection;
22     }
23 
24     public static void closeConnection(Connection con, PreparedStatement ps, ResultSet rs) {
25         if (rs != null) {
26             try {
27                 rs.close();
28             } catch (SQLException e) {
29                 e.printStackTrace();
30             }
31         }
32         if (ps != null) {
33             try {
34                 ps.close();
35             } catch (SQLException e) {
36                 e.printStackTrace();
37             }
38         }
39         if (con != null) {
40             try {
41                 con.close();
42             } catch (SQLException e) {
43                 e.printStackTrace();
44             }
45         }
46     }
47 }

 










以上是关于JDBC对MySQL数据库存储过程的调用的主要内容,如果未能解决你的问题,请参考以下文章

jdbc调用mysql存储过程实现代码带有输入和输出

Java调用MySQL存储过程

我可以在 jdbc 中调用一个使用 mysql 返回表的存储过程吗?

部分代码片段

SQL存储过程如何调用存储过程?

MySQL 和 JDBC 缓存(?)问题与 Scala 中的过程调用有关