JDBC(MySQL)——DAY04(调用存储过程,存储函数)

今天针对JDBC中调用存储过程和存储函数进行了学习,学习内容如下:

1.JDBC中调用存储过程:

调用存储过程需要用到PreparedCall,专门用来处理调用存储过程和存储函数,迄今为止我学了三个Connection创建的陈述对象了,Statement,PreparedStatement和PreparedCall三个,前两个区别在于Statement是在executeQuery/ExecuteUpdate的时候进行SQL语句的执行,而PreparedStatement是在初始化的时候传入SQL语句,并在指定参数部位传入?占位,并在后续使用setObject/String/Int/Blob...进行参数设置,设置好之后使用execute执行SQL,Statement的执行流程是:解析->编译->优化->执行就是连续下来的一个过程,PreparedStatement的执行流程是:解析->编译->优化->缓存执行计划,然后在后续调用execute之后再执行,而PreparedCall的执行则是和PreparedStatement相同,只不过作用的是存储过程和存储函数罢了;

(1)调用无参的存储过程

javascript 复制代码
create procedure noparam()
begin
select * from emp;
end;
javascript 复制代码
public class TestNoParam {
    public static void main(String[] args) throws SQLException {
        //Statement
        //PreparedStatement
        Connection connection = DBUtil.getConnection();
        String sql = "{call noparam()}";
        CallableStatement callableStatement = connection.prepareCall(sql);
        callableStatement.execute();//执行了存储过程
        ResultSet resultSet = callableStatement.getResultSet();
        //ResultSet resultSet = callableStatement.executeQuery();
        while (resultSet.next()) {
            System.out.print(resultSet.getString(1) + "\t");
            System.out.print(resultSet.getString(2) + "\t");
            System.out.print(resultSet.getString(3) + "\t");
            System.out.print(resultSet.getString(4) + "\t");
            System.out.print(resultSet.getString(5) + "\t");
            System.out.println(resultSet.getString(6) + "\t");
        }
        DBUtil.close(callableStatement, connection);
    }
}

(2)有入参的存储过程调用

sql 复制代码
create procedure sell_pro(goodsId varchar(30),orderId varchar(32),n int)
begin
start transaction ;
insert into order_info values (default,goodsId,orderId,n);
update stock set num=num-n where goods_id=goodsId;
insert into records values (default,goodsId,n,now());
commit ;
end;
java 复制代码
public class TestInParam {
public static void main(String[] args) throws SQLException {
Connection connection= DBUtil.getConnection();
String sql="{call sell_pro(?,?,?)}";
CallableStatement callableStatement = connection.prepareCall(sql);
callableStatement.setString(1,"1001");
callableStatement.setString(2,"20230102");
callableStatement.setInt(3,20);
callableStatement.execute();
DBUtil.close(callableStatement,connection);
}
}

(3)既有入参又有出参的存储过程调用:

sql 复制代码
create procedure add_test( a int, b int,out c int )
begin
set c=a+b;
end;
java 复制代码
public class TestOutParam {
public static void main(String[] args) throws SQLException {
Connection connection= DBUtil.getConnection();
String sql="{call add_test(?,?,?)}";
CallableStatement callableStatement = connection.prepareCall(sql);
callableStatement.setInt(1,10);
callableStatement.setInt(2,20);
//对应out参数的处理,标注参数类型
callableStatement.registerOutParameter(3, Types.INTEGER);
callableStatement.execute();
int anInt = callableStatement.getInt(3);
System.out.println(anInt);
DBUtil.close(callableStatement,connection);
}
}

(4)有特殊参数(INOUT)的调用

sql 复制代码
create procedure mul(inout res int)
begin
set res=res*10;
end;
java 复制代码
public class TestInOutParam {
public static void main(String[] args) throws SQLException {
Connection connection= DBUtil.getConnection();
String sql="{call mul(?)}";
CallableStatement callableStatement = connection.prepareCall(sql);
callableStatement.setInt(1,5);
//对应out参数的处理,标注参数类型
callableStatement.registerOutParameter(1, Types.INTEGER);
callableStatement.execute();
int anInt = callableStatement.getInt(1);
System.out.println(anInt);
DBUtil.close(callableStatement,connection);
}
}

(6)存储结果查询了多个结果集:

sql 复制代码
create procedure selectMul(goodsId varchar(30))
begin
select * from order_info where goods_id = goodsId;
select * from stock where goods_id = goodsId;
select * from records where goods_id = goodsId;
end;
java 复制代码
package demo;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;

/**
 * @author djw
 */
public class Test5 {
    public static void main(String[] args) throws Exception {
        Connection conn = DBUtil.getConnection();
        CallableStatement callableStatement = conn.prepareCall("{call selectMul(?)}");
        callableStatement.setString(1, "1001");
        callableStatement.execute();
        ResultSet rs = callableStatement.getResultSet();
        while(rs.next()) {
            for(int i = 1; i <= rs.getMetaData().getColumnCount(); i++) {
                System.out.print(rs.getString(i) + "\t");
            }
        }
        System.out.println("---------------------");
        while (callableStatement.getMoreResults()) {
            ResultSet resultSet = callableStatement.getResultSet();
            while(resultSet.next()) {
                for(int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
                    System.out.print(resultSet.getString(i) + "\t");
                }
            }
            System.out.println();
            System.out.println("--------------------");
        }
        DBUtil.close(conn, callableStatement);
    }
}

这里可以使用元数据getMetaData来获取有多少行的统计值,以便于进行打印

2.再创建Statement/PreparedStatement/PreparedCall的时候可以传入参数以设置结果集的可滚动性,可更新性等特点:

3.调用函数:

java 复制代码
public class TestFunction {
public static void main(String[] args) throws SQLException {
Connection connection= DBUtil.getConnection();
//调用自定义函数
CallableStatement callableStatement =
connection.prepareCall("{?=call getHiredate(?)}");
callableStatement.registerOutParameter(1, Types.DATE);
callableStatement.setString(2,"白居易");
callableStatement.execute();
System.out.println(callableStatement.getDate(1));
DBUtil.close(callableStatement,connection);
}
}

方式与有out参数的存储过程相似,只不过语法有所改变;

相关推荐
2401_891409262 小时前
量化数据13:港股分钟K线、Level2逐笔Tick、十档盘口和港股通历史数据的批量提取
数据库
w-w0w-w8 小时前
SQL注入
网络·数据库·sql
tianyuanwo8 小时前
NetBox 数据库详解:当“关系型数据库”被装进一个网络运维的领域模型里
运维·数据库·netbox
一条泥憨鱼8 小时前
【计算机网络】短连接、长连接与连接池:从 TCP 握手到池化复用的完整链路
网络·数据库·网络协议·tcp/ip·计算机网络
天河归来9 小时前
第三方接口不稳定,如何让核心任务继续完成
java·大数据
IvorySQL9 小时前
深入 PostgreSQL WAL:从崩溃恢复到逻辑复制
数据库·postgresql
Knight_AL9 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
幽灵诶10 小时前
Mysql(基于测试的学习)
数据库·mysql
砚底藏山河10 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
宇宙无敌暴龙战士66611 小时前
MySQL 8 库表操作学习笔记:SQL 基础、库表管理、约束与用户授权全流程
数据库·sql·mysql·学习笔记·后端开发