编程开发之--Oracle数据库--存储过程和存储函数(2)

上一小结我们简单介绍了存储过程和存储函数,对存储过程和存储函数有了一个基本的了解,接下来介绍在java程序中如何调用我们创建的存储过程和存储函数

1、在应用程序中调用我们的存储过程

      创建一个简单的Java工程,如:TestOracle,在项目中新建lib文件夹,并拷贝ojdbc14.jar,添加到系统路径中,目录结构如下:

      在项目中创建一个用于连接数据库以及与数据库执行交流的工具类JDBCUtils.java

package demo.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class JDBCUtils {

	private static String driver="oracle.jdbc.OracleDriver";
	private static String url="jdbc:oracle:thin:@localhost:1521:orcl";
	private static String user="scott";
	private static String password="scott";
	
	//注册数据库驱动
	static {
		try {
			Class.forName(driver);
//			DriverManager.registerDriver(driver);
		} catch (Exception e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	
	//获取数据库连接
	public static Connection getConnection() {
		try {
			return DriverManager.getConnection(url, user, password);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	//释放数据库资源
	public static void release(Connection conn,Statement st,ResultSet rs) {
		if(rs!=null) {
			try {
				rs.close();
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				rs=null;
			}
		}
		
		if(st!=null) {
			try {
				st.close();
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				st=null;
			}
		}
		
		if(conn!=null) {
			try {
				conn.close();
			} catch (Exception e) {
				e.printStackTrace();
			}finally {
				conn=null;
			}
		}
	}
}

  创建我们的测试包,在包中创建我们的测试类TestProcedure.java

package demo.oracle;

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

import org.junit.Test;

import demo.utils.JDBCUtils;
import oracle.jdbc.internal.OracleTypes;

public class TestProcedure {

	/**
	 * create or replace PROCEDURE queryempinform(eno in number,
		                                          pename out varchar2,
		                                          psal out number,
		                                          pjob out varchar2)*/
	@Test
	public void testProcedure() {
		//{call <procedure-name>[(<arg1>,<arg2>,...)]}
		String sql="{call queryempinform(?,?,?,?)}";
		Connection conn=null;
		CallableStatement call=null;
		try {
			//得到一个连接
			conn=JDBCUtils.getConnection();
            //通过连接创建出statment
			call=conn.prepareCall(sql);
			
			//对in参数进行赋值
			call.setInt(1, 7839);
			
			//对out参数进行申明
			call.registerOutParameter(2, OracleTypes.VARCHAR);
			call.registerOutParameter(3, OracleTypes.NUMBER);
			call.registerOutParameter(4, OracleTypes.VARCHAR);
			
			//设置文笔之后,开始我们的存储过程的调用
			call.execute();
			
			//取出结果
			String name=call.getString(2);
			double sal=call.getDouble(3);
			String job=call.getString(4);
			System.out.println(name+"\t"+sal+"\t"+job);
			
		} catch (Exception e) {
			//遇到异常将其打印到控制台输出
			e.printStackTrace();
		}finally {
			//释放数据库资源
			JDBCUtils.release(conn, call, null);
		}
	}
}

  启动我们的单元测试,运行结果:

 

2、在应用程序中调用我们的存储函数

     在测试包中创建我们的测试类TestFunction.java

package demo.oracle;

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

import org.junit.Test;

import demo.utils.JDBCUtils;
import oracle.jdbc.internal.OracleTypes;

public class TestFunction {

	/**
	 * create or replace FUNCTION queryempincome(eno in number)
       return number
     */
	@Test
	public void testFunction() {
		//{?=call <procedure-name>[(<arg1>,<arg2>,...)]}
		String sql="{?=call queryempincome(?)}";
		
		Connection conn=null;
		CallableStatement call=null;
		try {
			//得到数据库连接
			conn=JDBCUtils.getConnection();
			
			//基于连接得到statment
			call=conn.prepareCall(sql);
			
			//对in参数赋值
			call.setInt(2, 7839);
			
			//对out参数进行申明
			call.registerOutParameter(1, OracleTypes.NUMBER);
			
			//执行我们存储函数的调用
			call.execute();
			
			//取得我们的结果
			double income=call.getDouble(1);
			System.out.println("该员工的年收入是:"+income);
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			JDBCUtils.release(conn, call, null);
		}
	}
}

  启动我们的单元测试,运行结果:

 

3、返回游标,读取游标中的数据

  在测试包中创建我们的测试类TestCursor.java

package demo.oracle;

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

import org.junit.Test;

import demo.utils.JDBCUtils;
import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.internal.OracleTypes;

public class TestCursor {

    /**
     * create or replace PACKAGE MYPACKAGE AS 
          type empcursor is ref cursor;
          procedure queryEmpList(dno in number,empList out empcursor);
       END MYPACKAGE;
     */
    @Test
    public void testCursor(){
        //{call <procedure-name>[(<agr1>,<agr2>,...)]}
        String sql="{call MYPACKAGE.queryEmpList(?,?)}";
        Connection conn=null;
        CallableStatement call=null;
        ResultSet rs=null;
        try {
            //获得数据库连接
            conn=JDBCUtils.getConnection();
            
            //根据连接创建statment
            call=conn.prepareCall(sql);
            
            //对in参数赋值
            call.setInt(1, 10);
            
            //对out参数进行申明
            call.registerOutParameter(2, OracleTypes.CURSOR);
            
            //执行我们的调用
            call.execute();
            
            //取出该部门中所有员工的信息,由于我们当前是Oracle的光标,Oracle的存储过程,所以我们要对call进行转换
            rs=((OracleCallableStatement)call).getCursor(2);
            while(rs.next()){
                //取出该员工的员工号、姓名、薪水、职位字段作为示例
                int empno = rs.getInt("empno");
                String name = rs.getString("ename");
                double salary = rs.getDouble("sal");
                String job = rs.getString("job");
                System.out.println(empno+"\t"+name+"\t"+salary+"\t"+job);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.release(conn, call, rs);
        }
    }
}

  启动我们的单元测试,即可看到逐一打印我们从数据库查询到的结果。

 

posted @ 2018-06-19 01:32  ZeroMZ  阅读(378)  评论(0编辑  收藏  举报