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/[email protected] -v -r g:\com\test\JspSendMsg.java
其中,
u---參數表示連接配接資料庫的使用者
v---加載時輸出詳細日志
r---加載時利用oracle jvm進行解析,生成class檔案
--加載java class檔案
loadjava -u scott/[email protected] -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/[email protected] -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/[email protected] -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/[email protected] -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/[email protected] -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列值