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参数的存储过程相似,只不过语法有所改变;

相关推荐
数智化管理手记5 小时前
精益生产中的TPM管理是什么?一文破解设备零故障的密码
服务器·网络·数据库·低代码·制造·源代码管理·精益工程
翊谦6 小时前
Java Agent开发 Milvus 向量数据库安装
java·数据库·milvus
晓晓hh6 小时前
JavaSE学习——迭代器
java·开发语言·学习
查古穆6 小时前
栈-有效的括号
java·数据结构·算法
Java面试题总结6 小时前
Spring - Bean 生命周期
java·spring·rpc
硅基诗人6 小时前
每日一道面试题 10:synchronized 与 ReentrantLock 的核心区别及生产环境如何选型?
java
014-code6 小时前
String.intern() 到底干了什么
java·开发语言·面试
難釋懷7 小时前
OpenResty实现Redis查询
数据库·redis·openresty
别抢我的锅包肉7 小时前
【MySQL】第四节 - 多表查询、多表关系全解析
数据库·mysql·datagrip
Database_Cool_7 小时前
OpenClaw-Observability:基于 DuckDB 构建 OpenClaw 的全链路可观测体系
数据库·阿里云·ai