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列值