0

0

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

php中文网

php中文网

发布时间:2016-06-01 13:07:17

|

1045人浏览过

|

来源于php中文网

原创

一、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数据库存储过程的调用,这里直接以例子的形式展示。

成新网络商城购物系统
成新网络商城购物系统

使用模板与程序分离的方式构建,依靠专门设计的数据库操作类实现数据库存取,具有专有错误处理模块,通过 Email 实时报告数据库错误,除具有满足购物需要的全部功能外,成新商城购物系统还对购物系统体系做了丰富的扩展,全新设计的搜索功能,自定义成新商城购物系统代码功能代码已经全面优化,杜绝SQL注入漏洞前台测试用户名:admin密码:admin888后台管理员名:admin密码:admin888

下载

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”关键字的位置你一定深有收获,呵呵呵,偷点懒,在此就不总结了。*//** * 输入参数即输出参数的存储过程 *  * @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','泰国');

【0分下载演示资源】

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Python 序列化
Python 序列化

本专题整合了python序列化、反序列化相关内容,阅读专题下面的文章了解更多详细内容。

0

2026.02.02

AO3官网入口与中文阅读设置 AO3网页版使用与访问
AO3官网入口与中文阅读设置 AO3网页版使用与访问

本专题围绕 Archive of Our Own(AO3)官网入口展开,系统整理 AO3 最新可用官网地址、网页版访问方式、正确打开链接的方法,并详细讲解 AO3 中文界面设置、阅读语言切换及基础使用流程,帮助用户稳定访问 AO3 官网,高效完成中文阅读与作品浏览。

91

2026.02.02

主流快递单号查询入口 实时物流进度一站式追踪专题
主流快递单号查询入口 实时物流进度一站式追踪专题

本专题聚合极兔快递、京东快递、中通快递、圆通快递、韵达快递等主流物流平台的单号查询与运单追踪内容,重点解决单号查询、手机号查物流、官网入口直达、包裹进度实时追踪等高频问题,帮助用户快速获取最新物流状态,提升查件效率与使用体验。

27

2026.02.02

Golang WebAssembly(WASM)开发入门
Golang WebAssembly(WASM)开发入门

本专题系统讲解 Golang 在 WebAssembly(WASM)开发中的实践方法,涵盖 WASM 基础原理、Go 编译到 WASM 的流程、与 JavaScript 的交互方式、性能与体积优化,以及典型应用场景(如前端计算、跨平台模块)。帮助开发者掌握 Go 在新一代 Web 技术栈中的应用能力。

11

2026.02.02

PHP Swoole 高性能服务开发
PHP Swoole 高性能服务开发

本专题聚焦 PHP Swoole 扩展在高性能服务端开发中的应用,系统讲解协程模型、异步IO、TCP/HTTP/WebSocket服务器、进程与任务管理、常驻内存架构设计。通过实战案例,帮助开发者掌握 使用 PHP 构建高并发、低延迟服务端应用的工程化能力。

5

2026.02.02

Java JNI 与本地代码交互实战
Java JNI 与本地代码交互实战

本专题系统讲解 Java 通过 JNI 调用 C/C++ 本地代码的核心机制,涵盖 JNI 基本原理、数据类型映射、内存管理、异常处理、性能优化策略以及典型应用场景(如高性能计算、底层库封装)。通过实战示例,帮助开发者掌握 Java 与本地代码混合开发的完整流程。

5

2026.02.02

go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

62

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

55

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

27

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号