博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JDBC对MySQL数据库存储过程的调用
阅读量:6000 次
发布时间:2019-06-20

本文共 8899 字,大约阅读时间需要 29 分钟。

        一、MySQL数据库存储过程:

        1、什么是存储过程

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

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

        长处:

        1)、降低了脚本的运行环节,缩短了获取数据的时间。存储过程仅仅在创建的时进行编译,在调用使用的时候直接运行。不需再次编译;而一般SQL语句每次运行前都须要编译一次,故效率没有存储过程高。
        2)、降低网络传输量,提高了传输速度。

存储过程编译后存储在数据库server上,使用的时候仅仅须要指定存储过程的名字并给出參数(假设该存储过程带有參数)就能够了;而一般SQL语句须要将所运行语句字符串传输到数据库server端。相比于存储过程而言向数据库服务端传送的字符串长度比較大;

        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、没有不论什么输入和输出參数的存储过程

package com.ghj.packageoftest;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import com.ghj.packageoftool.LinkDB;/*运行本程序前需运行的脚本:DELIMITER $$//DELIMITER和$$之间要么没有空格要么仅仅有一个空格,假设有多个空格,在运行创建存储过程语句时你会发现这样是不能创建成功的CREATE PROCEDURE noParam()BEGINSELECT AVG(price) AS priceAvg FROM fruit;END$$DELIMITER ;*//** * 没有不论什么输入和输出參数的存储过程 *  * @author GaoHuanjie */public class NoParam {	public static void main(String args[]) throws SQLException {		Connection connection = LinkDB.getMySqlConnection();		String proStr = "{call noParam}";		CallableStatement callableStatement = connection.prepareCall(proStr);		callableStatement.execute();		ResultSet resultSet = callableStatement.getResultSet();		while (resultSet.next()) {			System.out.println("产品的平均价格是:" + resultSet.getDouble("priceAvg") + "元");		}		LinkDB.close(connection, callableStatement, resultSet);	}}

        2、仅仅有两个输入參数的存储过程

package com.ghj.packageoftest;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.ResultSet;import java.sql.SQLException;import com.ghj.packageoftool.LinkDB;/*执行本程序前需执行的脚本:DELIMITER $$CREATE PROCEDURE inTwoParam(IN fruitName VARCHAR(12),IN fruitPrice DECIMAL(9,2))//说明:fruitPrice參数的数据类型与price列的数据类型不一致(price的类型为(8,2)),对这一现象应该有所感悟。BEGINSELECT * FROM fruit WHERE NAME LIKE CONCAT('%',fruitName,'%') AND price < fruitPrice;//注意:CONCAT('%',fruitName,'%')不能为'%'+fruitName+'%'END$$DELIMITER ;*//** * 仅仅有两个输入參数的存储过程 *  * @author GaoHuanjie */public class InTwoParam {	public static void main(String args[]) throws SQLException {		Connection connection = LinkDB.getMySqlConnection();		String procStr = "{call inTwoParam(?

,?)}"; CallableStatement callableStatement = connection.prepareCall(procStr); callableStatement.setString(1, "莲"); callableStatement.setDouble(2, 88.88);//对DECIMAL类型的属性设值要使用setDouble方法。 callableStatement.execute(); ResultSet resultSet = callableStatement.getResultSet(); System.out.println("名称包括‘莲’字且价格小于88.88元的水果有:"); while (resultSet.next()) { System.err.println("名称:" + resultSet.getString("name") +"、价格:" + resultSet.getDouble("price") + "元"+"、产地:" + resultSet.getString("address")); } LinkDB.close(connection, callableStatement, resultSet); } }

        3、仅仅有两个输出參数的存储过程

package com.ghj.packageoftest;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.SQLException;import java.sql.Types;import com.ghj.packageoftool.LinkDB;/*执行本程序前需执行的脚本:DELIMITER $$CREATE PROCEDURE outTwoParam(OUT fruitName VARCHAR(12),OUT fruitPrice DECIMAL(5,3) )BEGINSELECT name INTO fruitName FROM fruit WHERE name='莲雾';SELECT price INTO fruitPrice FROM fruit WHERE NAME='莲雾';END $$DELIMITER ;注意:上面两条查询语句不能合成一个SQL语句——SELECT NAME INTO fruitName, price INTO fruitPrice FROM fruit WHERE NAME='莲雾';*//** * 仅仅有两个输出參数的存储过程 *  * @author GaoHuanjie */public class OutTwoParam {	public static void main(String args[]) throws SQLException {		Connection connection = LinkDB.getMySqlConnection();		String proStr = "{call outTwoParam(?

,?)}"; CallableStatement callableStatement = connection.prepareCall(proStr); callableStatement.registerOutParameter(1, Types.VARCHAR); callableStatement.registerOutParameter(2, Types.DECIMAL); callableStatement.execute(); String fruitName = callableStatement.getString(1); double fruitPrice = callableStatement.getDouble(2);// 获取DECIMAL类型的属性要使用getDouble方法。

System.out.println("水果名称:" + fruitName +"、水果价格:" + fruitPrice + "元"); LinkDB.close(connection, callableStatement, null); } }

        4、含有一个输入參数和一个输出參数的存储过程

package com.ghj.packageoftest;import java.sql.CallableStatement;import java.sql.Connection;import java.sql.SQLException;import java.sql.Types;import com.ghj.packageoftool.LinkDB;/*执行本程序前需执行的脚本:DELIMITER $$CREATE PROCEDURE inOneParamAndOutOneParam(IN fruitName VARCHAR(12),OUT fruitPrice DECIMAL(7,3))BEGINSELECT price FROM fruit WHERE NAME=fruitName INTO fruitPrice;END $$DELIMITER ;*/ /** * 含有一个输入參数和一个输出參数的存储过程 *  * @author GaoHuanjie */public class InOneParamAndOutOneParam {	public static  void main(String args[]) throws SQLException {		Connection connection=LinkDB.getMySqlConnection();		CallableStatement callableStatement=null;		String procStr="{call inOneParamAndOutOneParam(?

,?)}"; callableStatement=connection.prepareCall(procStr); String fruitName = "莲雾"; callableStatement.setString(1, fruitName); callableStatement.registerOutParameter(2, Types.DECIMAL); callableStatement.execute(); double fruitPrice=callableStatement.getDouble(2);//获取DECIMAL类型的属性要使用getDouble方法。

System.out.println(fruitName+"的价格为:"+fruitPrice+"元"); LinkDB.close(connection, callableStatement, null); } }

        5、输入參数即输出參数的存储过程

package com.ghj.packageoftest;import java.sql.*;import com.ghj.packageoftool.LinkDB;/* 执行本程序前需执行的脚本:DELIMITER $$CREATE PROCEDURE inOneParamISOutOneParam(INOUT fruitName VARCHAR(12))BEGINSELECT NAME INTO fruitName FROM fruit WHERE NAME LIKE CONCAT('%', fruitName, '%') LIMIT 0,1;END $$DELIMITER ;或DELIMITER $$CREATE PROCEDURE inOneParamISOutOneParam(INOUT fruitName VARCHAR(12))BEGINSELECT NAME FROM fruit WHERE NAME LIKE CONCAT('%', fruitName, '%') LIMIT 0,1 INTO fruitName;END $$DELIMITER ;注意上面查询语句不能这样写:SELECT NAME FROM fruit WHERE NAME LIKE CONCAT('%', fruitName, '%') INTO fruitName LIMIT 0,1;注意:对照3、4和5Java文件内创建存储过程脚本中“INTO”keyword的位置你一定深有收获。呵呵呵,偷点懒。在此就不总结了。*//** * 输入參数即输出參数的存储过程 *  * @author GaoHuanjie */public class InOneParamISOutOneParam {	public static void main(String args[]) throws SQLException {		Connection con = LinkDB.getMySqlConnection();		CallableStatement callableStatement = null;		String procStr = "{call inOneParamISOutOneParam(?

)}"; callableStatement = con.prepareCall(procStr); callableStatement.setString(1, "莲"); callableStatement.registerOutParameter(1, Types.VARCHAR); callableStatement.execute(); String fruitName = callableStatement.getString(1); System.out.println("表中水果名称含有‘莲’字的一中水果的名称是:" + fruitName); LinkDB.close(con, callableStatement, null); } }

        说明:

        1、假设把上面代码拷贝下来你会发现缺少LinkDB类,现贴出该类:

package com.ghj.packageoftool;import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;/** * 连接数据库 *  * @author GaoHuanjie */public class LinkDB {	/**	 * 功能:获取与MySql的连接	 * 	 * @author GaoHuanjie	 */	public static Connection getMySqlConnection() {		Connection connection = null;		String url = "jdbc:mysql://localhost:3306/test";		String user = "root";		String pwd = "";		String driverName = "com.mysql.jdbc.Driver";		try {			Class.forName(driverName);			connection = DriverManager.getConnection(url, user, pwd);		} catch (ClassNotFoundException e) {			e.printStackTrace();		} catch (SQLException e) {			e.printStackTrace();		} 		return connection;	}	/**	 * 关闭释放全部的资源	 * 	 * @author GaoHuanjie	 */	public static void close(Connection con, PreparedStatement ps, ResultSet rs) {		if (rs != null){			try {				rs.close();			} catch (SQLException e) {				e.printStackTrace();			}		}		if (ps != null){			try {				ps.close();			} catch (SQLException e) {				e.printStackTrace();			}		}		if (con != null){			try {				con.close();			} catch (SQLException e) {				e.printStackTrace();			}		}	}}

        2、假设运行创建存储过程的SQL脚本,你会发现缺少名为fruit类。现贴出创建该表的SQL语句:

CREATE DATABASE `test`;USE `test`;CREATE TABLE `fruit` (  `id` char(36) NOT NULL COMMENT '标识',  `name` varchar(12) NOT NULL COMMENT '名称',  `price` decimal(8,2) NOT NULL COMMENT '单位价格',  `address` varchar(300) DEFAULT NULL COMMENT '产地',   PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='水果表';insert  into `fruit`(`id`,`name`,`price`,`address`) values ('27640c30-8df5-4cf2-916e-c28e0b2b1b52','山竹','24.45','马来西亚'),('46ac8392-9922-4593-89a3-517a9e516733','菠萝','19.41','巴西'),('63061a9f-3a0e-4140-98e0-8b1e13e4eab3','哈密瓜','17.77','中国'),('7ef0c286-b8b1-4e1e-9a8a-36bce703cf18','鳄梨','30.80','墨西哥'),('a1cf5251-9311-4c7f-be10-3532d8c16291','树莓','117.50','瑞士'),('c397aed0-a39a-49c5-91ee-7fc0579ddb20','莲雾','77.33','印度尼西亚'),('e8068fa1-a8e7-4025-89e2-36c1d5d23c74','榴莲','16.50','泰国');

        【

转载地址:http://nhbmx.baihongyu.com/

你可能感兴趣的文章
杂题 P1640 [SCOI2010]连续攻击游戏
查看>>
第五章 条件与判断
查看>>
MD5加密
查看>>
16个不错的Visual Studio插件(转)
查看>>
CSS常见居中讨论
查看>>
Update与Mysql、Sqlsever中的随机数
查看>>
Unity3D的坑系列:动态加载dll
查看>>
Nginx 安装与详解
查看>>
python pickle
查看>>
MySQL 5.7.9版本sql_mode=only_full_group_by问题
查看>>
企业级缓存系统varnish应用
查看>>
python day01
查看>>
数据字典的设计--1.首页功能实现
查看>>
win7 右键菜单残影 消除方法
查看>>
泰坦尼克 学习
查看>>
BZOJ 3717: [PA2014]Pakowanie
查看>>
JAVA的Date类与Calendar类(常用方法)
查看>>
远程控制centOS桌面
查看>>
leetcode345
查看>>
leetcode540
查看>>