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

相关推荐
plainGeekDev8 分钟前
ButterKnife → ViewBinding
android·java·kotlin
GBASE14 小时前
G术时刻 |GBase 8s数据库事务并发控制之封锁技术介绍(下)
数据库
像我这样帅的人丶你还16 小时前
Java 后端详解(四):分页与搜索
java·javascript·后端
她的男孩16 小时前
数据权限为什么不能只靠注解?Forge 的 Mapper 层 SQL 改写源码拆解
java·后端·架构
tntxia17 小时前
Mybatis的日志输入
java
亦暖筑序18 小时前
Java 8老系统Browser Agent实战:三层拦截把AI操作后台变成可审计流程
java·后端·设计模式
用户2986985301421 小时前
Java 实现 Word 文档加密与权限解除
java·后端
Yeats_Liao1 天前
14:Servlet中的页面跳转-Java Web
java·后端·架构
未秃头的程序猿1 天前
告别"if-else地狱"!Java 21模式匹配,代码优雅了10倍
java·后端·面试
鹤望兰6751 天前
字节跳动国际支付-后端开发-三面面经
java