java存儲過程開發總結

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

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章