Oracle存储过程(自定义函数)调用java类

由于项目需要,需要在存储过程中调用java类,特在此进行总结。

环境: centos764bit  jdk7 oracle10g64bit

先编写java代码 Demo.java,代码如下:

 

package com.longshine.procedure;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

public class Demo {
	public static String url = "url not set";
	public static String userName = "userName not set";
	public static String pwd = "pwd not set";
	public static String query(String arg){
		String result = "";
		init();
		result = "arg is "+arg +" & url:" + url;
		return result;
	}
	public static void main(String[] args){
		init();
		System.out.println("arg is "+args[0] +" & url:" + url);
	}
	public static void init(){
		Properties props = new Properties();
		try {
			props.load(new FileInputStream("/home/oracle/javademo/procedure.properties"));
			url = props.getProperty("url","url not set");
			userName = props.getProperty("userName","userName not set");
			pwd = props.getProperty("pwd","pwd not set");
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public static String helloWordFunction(){
		return "helloMoto";
	}
}

java代码存放于 /home/oracle/javademo/Demo.java

代码中用到的配置文件内容如下:

 

url=http://192.168.1.137
userName=aaa
pwd=bbb

配置文件存放于 /home/oracle/javademo/procedure.properties

我们的目的是通过JDBC调用存储过程或自定义函数来调用Demo.java的query方法,并取得返回值。

我们操作JDBC和存储过程使用的oracle用户为scott 密码为tiger

在linux命令行下执行

loadjava -u scott/tiger@orcl -v -resolve /home/oracle/javademo/Demo.java

这个命令可以在scott的用户下,载入java,供后续创建存储过程使用。

检查java是否load成功,在sqlplus中执行

SELECT a.OBJECT_NAME, a.OBJECT_TYPE,a.status FROM user_objects a WHERE a.OBJECT_NAME LIKE ‘%Demo%’;

 

创建自定义函数,在sqlplus中,使用scott用户执行

CREATE OR REPLACE FUNCTION fib (args String) RETURN VARCHAR2
AS LANGUAGE JAVA
NAME 'Demo.query(java.lang.String) return String';

 

由于我们要读取配置文件。所以需要用SYS用户对scott用户赋予读取配置文件的读文件权限。

使用SYS用户在sqlplus里执行

call dbms_java.grant_permission( ‘SCOTT’, ‘SYS:java.io.FilePermission’, ‘/home/oracle/javademo/procedure.properties’, ‘read’ );

 

如果我们想修改java类。那么可以在LINUX命令行中执行

dropjava -u scott -v Demo

然后修改java类,重新load 重建自定义函数即可。

 

下面是测试代码 TestProcedure.java:

 

 

package com.longshine.procedure;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Types;

public class TestProcedure {
	public static void main(String[] args) {
		new TestProcedure().testOracle();
	}
	/**
	 * 一个非常标准的连接Oracle数据库的示例代码
	 */
	public void testOracle()
	{
	    Connection con = null;// 创建一个数据库连接
	    PreparedStatement pre = null;// 创建预编译语句对象,一般都是用这个而不用Statement
	    ResultSet result = null;// 创建一个结果集对象
	    CallableStatement stmt = null;
	    try
	    {
	        Class.forName("oracle.jdbc.driver.OracleDriver");// 加载Oracle驱动程序
	        System.out.println("开始尝试连接数据库!");
	        String url = "jdbc:oracle:" + "thin:@192.168.1.137:1521:orcl";// 127.0.0.1是本机地址,XE是精简版Oracle的默认数据库名
	        String user = "scott";// 用户名,系统默认的账户名
	        String password = "tiger";// 你安装时选设置的密码
	        con = DriverManager.getConnection(url, user, password);// 获取连接
	        System.out.println("连接成功!");
	        String sql = "{? = call fib(?)}";
	        stmt = con.prepareCall(sql);
	        stmt.setString(2, "asss");
	        stmt.registerOutParameter(1, Types.LONGNVARCHAR);
	        stmt.execute();
	        String resultString = stmt.getNString(1);
	        System.out.println(resultString);
	    }
	    catch (Exception e)
	    {
	        e.printStackTrace();
	    }
	    finally
	    {
	        try
	        {
	        	if(stmt != null){
	        		stmt.close();
	        	}
	            if (result != null)
	                result.close();
	            if (pre != null)
	                pre.close();
	            if (con != null)
	                con.close();
	            System.out.println("数据库连接已关闭!");
	        }
	        catch (Exception e)
	        {
	            e.printStackTrace();
	        }
	    }
	}
}

执行main方法之后 控制台输出结果为

开始尝试连接数据库!
连接成功!
arg is asss & url:http://192.168.1.137
数据库连接已关闭!

 

 

至此 我们的目标已经达成。

调用无返回值的java方法时可以使用存储过程,调用有返回值的java方法时可以调用自定义函数,期间参考的英文网址为:

http://docs.oracle.com/cd/B28359_01/java.111/b31225/chthree.htm#CBBEJGIH