Java Stored Procedures(简称JSP,此JSP非彼JSP,哈哈哈),即JAVA存储过程,是通过Oracle数据库中的DML、package等调用JAVA程序,从而实现Oracle数据库与JAVA集成。由于工作需要,要通过Oracle数据库调用JAVA程序,与ActiveMQ集成实现消息发送,网上大多数例子都是通过Oracle数据库调用java程序实现最基本的Hello程序,更深入的研究也比较少。经过长时间的纠结,最终实现了消息发送,现总结如下,供需要的童鞋们参考。本文基于Oracle Database11g Release2。
1、主要参考资料
最基本参考资料就是Oracle官方文档:Oracle Database Java Developer's Guide
其他的就百度吧。
2、开发步骤
(1)编写JAVA程序
跟平常JAVA开发一样,该怎么编写就怎么编写,但要注意,通过数据库调用的方法必须为static的,下面为发送消息的JAVA代码框架:
package com.test;
/**
*
*
*/
public class JspSendMsg {
public static String sendMsg(String str){
//发送消息成功标志
String b = "Y";
System.out.println("发送消息开始。。。。");
try {
//实现消息发送,此处略
//......
System.out.println("发送消息成功!");
} catch (Exception e) {
// TODO: handle exception
System.out.println("发送消息失败!");
b = "N";
e.printStackTrace();
}
return b;
}
}
(2)加载JAVA类到数据库中
有两种方式:
a、通过pl/sql新建Java source,把第(1)步中java代码直接copy进来,编译即可;
create or replace and compile java source named JspSendMsg as
package com.test;
/**
*
*
*/
public class JspSendMsg {
public static String sendMsg(String str){
//发送消息成功标志
String b = "Y";
System.out.println("发送消息开始。。。。");
try {
//实现消息发送,此处略
//......
System.out.println("发送消息成功!");
} catch (Exception e) {
// TODO: handle exception
System.out.println("发送消息失败!");
b = "N";
e.printStackTrace();
}
return b;
}
}
b、利用loadjava工具
loadjava工具是oracle数据库提供的一个命令行工具,它可加载java源文件、java class类、jar包、资源文件到数据库中,根据需要自行选择。
--加载java源文件
loadjava -u scott/scott@orcl -v -r g:\com\test\JspSendMsg.java
其中,
u---参数表示连接数据库的用户
v---加载时输出详细日志
r---加载时利用oracle jvm进行解析,生成class文件
--加载java class文件
loadjava -u scott/scott@orcl -v g:\com\test\JspSendMsg.class
注意,加载已编译的class文件时需注意编译java类的JDK版本与Oracle jvm版本必须一致,否则可能会出问题,11g对应的JDK为1.5,10g为1.4。
(3)发布java类
发布java需在数据库中进行,通过package调用JspSendMsg类,发布如下:
package头:
function sendMsg(msg varchar2) return VARCHAR2;
package体:
function sendMsg(msg varchar2) return VARCHAR2 as
LANGUAGE JAVA NAME 'com.test.JspSendMsg.sendMsg(java.lang.String) return java.lang.String';
至此,编码部分基本完毕,在测试前还有些事情需要做。
(4)加载jar包
由于是实现消息发送,需要把activemq-all-5.2.0.jar加载进数据中。通过loadjava工具加载jar包时,由于待加载jar包可能依赖其他第三方jar包,需提供-genmissing参数,否则有些class文件无法编译。如有多个jar包,可一起加载。loadjava加载jar包时会解压jar文件,把jar中每个class进行分别加载。
命令形式:
loadjava -u scott/scott@orcl -genmissing -r -v -f -fileout active.txt activemq-all-5.2.0.jar
其中,
genmissing---表示如果该jar包里依赖其他jar包,而其他jar包数据库中并不存在,此时数据库会忽略,并产生该class文件,具体可参见loadjava工具说明。
f---强制加载
fileout---输出日志到文件active.txt中
(5)加载资源文件ia.properties
为编译维护,把消息服务器IP地址、端口、消息队列名称配置在配置文件中,需加载到数据库中,用户java程序解析该配置文件。
命令形式:
loadjava -user scott/scott@orcl -v ia.properties
注意,ia.properties前不能加其他路径,需在当前路径下执行,否则java程序找不到该配置文件。
(6)授权
通过Oracle数据库调用java程序时,需要进行授权,授权时需要DBA权限用户。本文主要用到以下两种:
--使用java类加载器时需进行此授权,本例中需要读取配置文件,因此需要此授权
call dbms_java.grant_permission( 'scott', 'SYS:java.lang.RuntimePermission', 'getClassLoader', '')
--访问网络时需要进行此授权
call dbms_java.grant_permission( 'scott', 'SYS:java.net.SocketPermission', '消息服务器IP地址:消息port', 'connect,resolve')
(7)至此,可以进行消息发送测试了。本例实现了简单的消息发送。
3、设置重定向
通过Oracle数据库调用java程序,不太好查看java程序里的输出信息,pl/sql提供了设置重定向功能,可将java程序里System.out等输出信息进行重定向,在pl/sql命令行窗口执行:
SET SERVEROUTPUT ON;
CALL dbms_java.set_output(2000);
然后调用程序时即可看到输出信息到命令行窗口。
4、最后提供一些有用的脚本。
--删除单个class
dropjava -user scott/scott@orcl -r -v -f com/test/JspSendMsg
--执行loadjava后查询一下状态
SELECT uo.created ,uo.object_name, uo.object_type, dbms_java.longname(uo.object_name),uo.status,uo.*
FROM user_objects uo WHERE 1=1
--and object_type like 'JAVA%'
order by uo.created desc;
--生成批量删除java类命令
select 'dropjava -u scott/scott@orcl -r -v -f '||dbms_java.longname(uo.object_name) FROM user_objects uo
WHERE object_type='JAVA CLASS';
--java数据库对象原名称与别名对应关系
select * from javasnm js;
--编译java源文件错误信息视图
select * from USER_ERRORS ue where ue.type like 'JAVA%';
--数据库中policy视图,用户查看当前用户被授予的权限
select * from USER_JAVA_POLICY;
--权限操作
--授权
见本文前面
--删除权限:需先收回再删除
call dbms_java.revoke_permission('scott', 'SYS:java.lang.RuntimePermission', 'getClassLoader', '*');
call dbms_java.delete_permission(key => 153); --153对应表user_java_policy.KIND列值