zoukankan      html  css  js  c++  java
  • 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")
                );
            }
  • 相关阅读:
    Windows Power Shell
    一个自律的人有多可怕!
    Android之TextureView浅析
    BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第9章节--client对象模型和REST APIs概览 介绍SP2013中远程APIs
    敌兵布阵(线段树)
    kendo AutoComplete实现多筛选条件
    Android 65K问题之Multidex原理分析及NoClassDefFoundError的解决方法
    让我心碎的五道题
    输入一列数组,输出它的逆序数组
    centos下配置防火墙port失败
  • 原文地址:https://www.cnblogs.com/zengyu1234/p/15549803.html
Copyright © 2011-2022 走看看