zoukankan      html  css  js  c++  java
  • 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 }
    
    
  • 相关阅读:
    树结构中的左右值计算
    Gitlab Runner实现NetCore自动化持续集成
    使用docker搭建gitlab服务器
    Linux笔记
    Miniprofiler在swagger、vue、angular中的使用
    MySqlException: The user specified as a definer ('root'@'%') does not exist解决方法
    从NetCore报错到MySql安全
    Asp.NetCore+Microsoft.AspNetCore.SignalR前后端分离
    学习sqlserve的一些笔记
    再见Jenkins,从Gitlab代码提交到k8s服务持续交付只需七毛三(走过路过不要错过)
  • 原文地址:https://www.cnblogs.com/silentmuh/p/7472988.html
Copyright © 2011-2022 走看看