JDBC调用存储过程

存储过程是数据库中一种预编译的SQL语句代码集,类似于Java的方法封装具有很高重用功能。

优点:执行效率高,提高访问速度。

缺点:更换数据库系统时存储过程不兼容。

JDBC API

CallableStatement接口是唯一处理数据库系统存储过程的通用组件

CallableStatement接口

CallableStatementPreparedStatement接口的子接口用来操作存储过程,此接口由Connection对象获得其实例

一个小插曲:遇到了一个报错:

java调用存储过程,不允许的操作: Ordinal binding and Named binding cannot be combined!

原因是给过程设置参数信息或取值的时候,不能够同时使用下标和名称来指定对应参数。

PL SQL创建一个存储过程:

create or replace procedure pro_querySubject(stuNumbers IN VARCHAR,subjectName IN VARCHAR,datas OUT sys_refcursor)
AS
BEGIN
  OPEN datas FOR select stu.numbers,cla.name,sub.name,sco.scores --查询结果使用系统引用游标类型接收
from students stu inner join score sco on stu.id = sco.stuid
inner join subject sub on sco.subid = sub.id
inner join classinfo cla on cla.id = stu.cid
where sub.name = stuNumbers and stu.numbers = subjectName;

END;

在相关Dao类中调用:

/**
     * 1 在数据库中定义一个存储过程,完成给定班级名称和学号及学科,
     * 获取此学生此学科成绩所有信息,在应用程序中定义相关方法完成调用此存储过程显示成绩信息。
     * @param stuNumbers
     * @param subjectName
     * @return
     */
    public List<Map<String,Object>> callProcedure3(String stuNumbers,String subjectName){
        List<Map<String,Object>> list = new ArrayList<>();
        String procName = "{call pro_querySubject(:stuNumbers,:subjectName,:datas)}";
        Connection conn = DataSourceManager.getConnection();//获取数据库连接
        CallableStatement call = null;
        ResultSet rs = null;
        try {
            call = conn.prepareCall(procName);//创建CallableStatement对象
            /* 注册oralce游标类型,此类型可以封装查询结果 */
            call.registerOutParameter("stuNumbers",Types.VARCHAR);
            call.setString("stuNumbers",stuNumbers);
            call.registerOutParameter("subjectName",Types.VARCHAR);
            call.setString("subjectName",subjectName);
            call.registerOutParameter("datas", oracle.jdbc.OracleTypes.CURSOR);
            call.execute();
            rs = (ResultSet) call.getObject("datas");//获取返回输出类型
            while(rs.next()){//遍历结果集封装为对象
                Map<String,Object> map = new HashMap<>();
                map.put("stuNumber",rs.getString(1));
                map.put("className",rs.getString(2));
                map.put("subName",rs.getString(3));
                map.put("scores",rs.getString(4));
                list.add(map);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            DataSourceManager.close(rs);
            DataSourceManager.close(call);
            DataSourceManager.close(conn);
        }
        return list;
    }

最后在测试类中调用输出

List<Map<String,Object>> list4 = new ScoreDao().callProcedure3("流体力学","110380");
        for(Map<String,Object> map:list4){
            System.out.println(map.get("stuNumber")
                    +"	"+map.get("className")
                    +"	"+map.get("subName")
                    +"	"+map.get("scores")
            );
        }
原文地址:https://www.cnblogs.com/zengyu1234/p/15549803.html