存储过程之七—java代码调用

本文涉及的产品
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: 一、简介   jdbc调用存储过程与调用一般的sql语句有些差别。jdbc调用一般的sql语句的时候,返回的是结果集,或是sql语句后是否执行成功的标记量。而存储过程返回的可以是结果集,输出参数、返回状态和受影响行数。

一、简介

  jdbc调用存储过程与调用一般的sql语句有些差别。jdbc调用一般的sql语句的时候,返回的是结果集,或是sql语句后是否执行成功的标记量。而存储过程返回的可以是结果集,输出参数、返回状态和受影响行数。而mysql存储过程不支持return,所以只有剩下的三种返回方式。

  调用的过程一般如下:

  1、创建连接 Connection conn = DriverManager.getConnection(url, user, password);

  2、创建CallableStatement CallableStatement statement = conn.prepareCall(sql);

  3、设置参数

    statement.setInt(1, id);
    statement.registerOutParameter(2, Types.VARCHAR);
    statement.registerOutParameter(3, Types.INTEGER);
    statement.registerOutParameter(4, Types.VARCHAR);

   4、执行

    statement.execute(); 或 statement.executeUpdate();

  5、获取返回

    int age = statement.getInt(3);或ResultSet resultSet = statement.executeQuery();

二、实例

  以下存储过程表结构如下:

DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) DEFAULT NULL,
    `age` int(11) DEFAULT NULL, 
  `password` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of person
-- ----------------------------
INSERT INTO `person` VALUES ('1', 'lisi', '21', 'li123456');
INSERT INTO `person` VALUES ('2', 'zhangsan', '23', 'zhang123456');

   1、增加记录(输入输出参数的调用)

     存储过程如下:

DROP PROCEDURE IF EXISTS proc_person_insert;
CREATE PROCEDURE proc_person_insert(
    IN uusername VARCHAR(255),
    IN uage INT(11),
    IN upassword VARCHAR(255),
    OUT flag INT(11)
)
BEGIN
    START TRANSACTION;
        INSERT INTO person (username, age, password) values (uusername, uage, upassword);
        SET flag = ROW_COUNT(); -- 保存sql语句操作后影响的行数
    COMMIT;    
END;

    调用代码如下:

 1     public static void insert(String username, int age, String upassword) {
 2         String driver = "com.mysql.jdbc.Driver";
 3         String url = "jdbc:mysql://127.0.0.1:3306/test";
 4         String user = "root";
 5         String password = "";
 6         try {
 7             Class.forName(driver);
 8             Connection conn = DriverManager.getConnection(url, user, password);
 9             String sql = "{call proc_person_insert( ?, ?, ?, ? )}";
10             CallableStatement statement = conn.prepareCall(sql);
11             statement.setString(1, username); //设置输入参数username
12             statement.setInt(2, age); //设置输入参数age
13             statement.setString(3, upassword);//设置输入参数password
14             statement.registerOutParameter(4, Types.INTEGER);//设置输出参数username
15             statement.executeUpdate();
16             int flag = statement.getInt(4);//获取输出参数
17             System.out.println(flag);// 1添加成功,0添加失败
18         } catch (ClassNotFoundException e) {
19             e.printStackTrace();
20         } catch (SQLException e) {
21             e.printStackTrace();
22         }
23     }

    对于输出参数需要调用statement.registerOutParameter(4, Types.INTEGER)进行注册,执行之后通过statement.getInt()方法来获取。

   2、修改记录(输入输出参数的调用)

    存储过程如下:

DROP PROCEDURE IF EXISTS proc_person_update;
CREATE PROCEDURE proc_person_update(
    IN uid INT(11),
    IN uusername VARCHAR(255),
    IN uage INT(11),
    IN upassword VARCHAR(255),
    OUT flag INT(11)
)
BEGIN
    START TRANSACTION;
        UPDATE person SET username = uusername, age = uage, password = upassword WHERE id = uid;
        SET flag = ROW_COUNT(); -- 保存sql语句操作后影响的行数
    COMMIT;
END;

    调用代码如下:

 1 public static void update(int id, String username, int age, String upassword) {
 2         String driver = "com.mysql.jdbc.Driver";
 3         String url = "jdbc:mysql://127.0.0.1:3306/test";
 4         String user = "root";
 5         String password = "";
 6         try {
 7             Class.forName(driver);
 8             Connection conn = DriverManager.getConnection(url, user, password);
 9             String sql = "{call proc_person_update( ?, ?, ?, ?, ? )}";
10             CallableStatement statement = conn.prepareCall(sql);
11             statement.setInt(1, id);
12             statement.setString(2, username);
13             statement.setInt(3, age); 
14             statement.setString(4, upassword); 
15             statement.registerOutParameter(5, Types.INTEGER);
16             statement.executeUpdate();
17             int flag = statement.getInt(5);
18             System.out.println(flag);// 1添加成功,0添加失败
19         } catch (ClassNotFoundException e) {
20             e.printStackTrace();
21         } catch (SQLException e) {
22             e.printStackTrace();
23         }
24     }

  3、删除记录(使用statement.getUpdateCount()获取影响行数)

    存储过程如下:

DROP PROCEDURE IF EXISTS proc_person_del;
CREATE PROCEDURE proc_person_del(
    IN pid INT(11) 
)
BEGIN 
    DELETE FROM person WHERE id = pid;  
END;

    调用代码如下:

 1 public  static void delete(int id){
 2         String driver = "com.mysql.jdbc.Driver";
 3         String url = "jdbc:mysql://127.0.0.1:3306/test";
 4         String user = "root";
 5         String password = "";
 6         try {
 7             Class.forName(driver);
 8             Connection conn = DriverManager.getConnection(url, user, password);
 9             String sql = "{call proc_person_del( ?)}";
10             CallableStatement statement = conn.prepareCall(sql); 
11             statement.setInt(1, id);
12             statement.executeUpdate();  
13             int flag = statement.getUpdateCount();//使用该语句的时候存储过程DELETE语句外不能出现 START TRANSACTION;COMMINT;
14             System.out.println(flag);
15         } catch (ClassNotFoundException e) { 
16             e.printStackTrace();
17         } catch (SQLException e) { 
18             e.printStackTrace();
19         }
20     }

   4、查询一条记录(输入输出)

     存储过程如下:

DROP PROCEDURE IF EXISTS proc_person_find;
CREATE PROCEDURE proc_person_find(
    IN pid INT(11),
    OUT pusername VARCHAR(255),
    OUT page INT(11),
    OUT ppassword VARCHAR(255)
)
BEGIN
    SELECT username, age, password INTO pusername, page, ppassword FROM person WHERE id = pid;
END;

    使用在SELECT语句中使用INTO给输出参数赋值

    调用代码如下:

 1     public  static void find(int id){
 2         String driver = "com.mysql.jdbc.Driver";
 3         String url = "jdbc:mysql://127.0.0.1:3306/test";
 4         String user = "root";
 5         String password = "";
 6         try {
 7             Class.forName(driver);
 8             Connection conn = DriverManager.getConnection(url, user, password);
 9             String sql = "{call proc_person_find( ?, ?, ?, ?)}";
10             CallableStatement statement = conn.prepareCall(sql);
11             statement.setInt(1, id);  
12             statement.registerOutParameter(2, Types.VARCHAR);
13             statement.registerOutParameter(3, Types.INTEGER);
14             statement.registerOutParameter(4, Types.VARCHAR);
15             statement.execute();
16             String username = statement.getString(2);
17             int age = statement.getInt(3);
18             String ppassword = statement.getString(4);
19             System.out.println("id:" + id);
20             System.out.println("username:" + username);
21             System.out.println("age:" + age);
22             System.out.println("ppassword:" + ppassword);
23         } catch (ClassNotFoundException e) {
24             e.printStackTrace();
25         } catch (SQLException e) {
26             e.printStackTrace();
27         }
28     }

  5、查询一个集合(返回一个集合)

    存储过程如下:

DROP PROCEDURE IF EXISTS proc_person_findAll;
CREATE PROCEDURE proc_person_findAll( )
BEGIN
    SELECT id, username, age, password  FROM person;
END;

    调用代码如下:

 1 public  static void findAll(){
 2         String driver = "com.mysql.jdbc.Driver";
 3         String url = "jdbc:mysql://127.0.0.1:3306/test";
 4         String user = "root";
 5         String password = "";
 6         try {
 7             Class.forName(driver);
 8             Connection conn = DriverManager.getConnection(url, user, password);
 9             String sql = "{call proc_person_findAll()}";
10             CallableStatement statement = conn.prepareCall(sql); 
11             ResultSet resultSet = statement.executeQuery();
12             while(resultSet.next()){
13                 int id = resultSet.getInt("id");
14                 String username =resultSet.getString("username");
15                 int age = resultSet.getInt("age");
16                 String ppassword = resultSet.getString("password");
17                 System.out.println(id + " " + username + " " + age + " " + ppassword);
18             } 
19         } catch (ClassNotFoundException e) { 
20             e.printStackTrace();
21         } catch (SQLException e) {
22              e.printStackTrace();
23         }
24     }

     通过statement.executeQuery()方法返回已经ResultSet,再对ResultSet进行遍历。

  关于存储过程存在into参数的时候,java代码中在设置输入参数之后,还需要注册输出参数,调用之后通过statement.get..方法拿到输出参数的值。如下:

    String sql = "{call proc_person_del( ? )}";
    CallableStatement statement = conn.prepareCall(sql);
    statement.setInt(1, id); 
    statement.registerOutParameter(1, Types.INTEGER);  
    // 注意此次注册out 的index 和上面的in 参数index 相同  
    statement.execute(); 
    int flag = statement.getInt(1); 
相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
25天前
|
Java 索引
Java实现扑克牌游戏 | 随机发牌 ( 过程拆分详解+完整代码 )
Java实现扑克牌游戏 | 随机发牌 ( 过程拆分详解+完整代码 )
|
17天前
|
Java 程序员 API
Java中的Lambda表达式:简化你的代码
【7月更文挑战第10天】Lambda表达式,这一Java 8的闪亮特性,为开发者提供了一种更为简洁、灵活的编程方式。本文将探讨Lambda表达式如何优化代码结构,提升开发效率,以及在实际项目中应用的一些实例。我们将从基础语法入手,逐步深入到高级用法,最后讨论其性能影响,旨在帮助读者全面理解并有效利用Lambda表达式。
43 20
|
6天前
|
JSON Java BI
一次Java性能调优实践【代码+JVM 性能提升70%】
这是我第一次对系统进行调优,涉及代码和JVM层面的调优。如果你能看到最后的话,或许会对你日常的开发有帮助,可以避免像我一样,犯一些低级别的错误。本次调优的代码是埋点系统中的报表分析功能,小公司,开发结束后,没有Code Review环节,所以下面某些问题,也许在Code Review环节就可以避免。
61 0
一次Java性能调优实践【代码+JVM 性能提升70%】
|
10天前
|
存储 缓存 JavaScript
|
27天前
|
Java Spring
JAVA注解:传统与现代的完美结合,你的代码值得拥有!
【6月更文挑战第29天】Java注解,作为连接传统与现代的编程工具,简化企业级应用开发,提升代码可读性和维护性。通过自定义注解如`@Loggable`,可以将行为(如日志记录)与方法实现分离,减少模板代码。使用AOP(如Spring)处理注解,实现行为拦截,增强代码灵活性和可扩展性。拥抱Java注解,让代码更现代、更高效!
39 16
|
17天前
|
监控 Java Maven
使用AspectJ实现Java代码的运行时织入
使用AspectJ实现Java代码的运行时织入
|
23天前
|
缓存 算法 安全
|
10天前
|
SQL Java 数据处理
实时计算 Flink版产品使用问题之使用MavenShadePlugin进行relocation并遇到只包含了Java代码而未包含Scala代码,该怎么办
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
15天前
|
Java 编译器 API
Java中的Lambda表达式:简化代码,提升性能
在Java 8中,Lambda表达式的引入为开发者提供了一种更加简洁、灵活的编程方式。本文将深入探讨Lambda表达式的概念、语法、使用场景及其在Java中的应用示例,帮助读者更好地理解和掌握这一强大工具,从而优化代码结构,提高开发效率。
|
19天前
|
监控 Java Maven
使用AspectJ实现Java代码的运行时织入
使用AspectJ实现Java代码的运行时织入