今天我們要介紹的是Oracle數據庫如何利用Java的存儲過程來溝通SQL,XML、以及Java、J2EE與Web的相關服務。如果你對其相關的實際操作有興趣了解的話,以下的文章將會給你提供相關的知識。
存儲過程(stored procedure)允許將運行於數據庫層中的持久性邏輯與運行於中間層中的商務邏輯有效地分離開來。這種分離可以降低整個應用程序的復雜性,並提供其重用性、安全性、性能和可伸縮性。
但是,妨礙存儲過程廣泛采用的一個主要障礙是不同數據庫廠商使用各種專有的、且依賴於數據庫的實現語言。使用基於Java的存儲過程可以解決這一問題。Oracle已經實現了ANSI標准,這些標准規定了從SQL中將靜態Java方法作為過程或函數進行調用的能力。這種實現被簡單地稱作"Java存儲過程"。
在本文中,你將了解基於Java的存儲過程如何幫助簡化商務邏輯、提高其性能,並擴展數據庫的功能。本文將介紹Oracle數據庫如何在數據庫內啟用基於Java的存儲過程。還會介紹Java存儲過程如何訪問數據,以及如何創建基本Java存儲過程。
選擇PL/SQL還是Java
在考慮Oracle存儲過程時,你可能會想到PL/SQL。不過,從Oracle8i開始,Oracle已經在數據庫中支持Java,從而為存儲過程提供了不同於PL/SQL的開放式和可移植的方法。我可以聽到"$64 000問題":"我如何在PL/SQL和Java之間做出選擇?我是否應當忘記已經學習的所有PL/SQL相關知識,而變為一個Java天地的新手?"
兩種語言都適用於數據庫編程,都有自己的優點和弱點。在決定選擇哪一種語言時,可以參考下面根據經驗得出的通用規則:
對於要求與SQL進行無縫集成的數據庫中心來說則邏輯使用PL/SQL,從而完成對數據庫對象、類型和特性的訪問。
出於與數據庫的無關性考慮時,可以選擇Java作為開放式的語言來取代PL/SQL,同時也為了集成和溝通SQL、XML、J2EE和Web服務等各個領域。
OralceJVM使得Java可以運行在數據庫中
從Oracle8i版本1(Oralce8.1.5)開始,Oracle便提供緊密集成的Java虛擬機(JVM),JVM支持Oralce的數據庫會話期結構。任何數據庫對話期都可以在第一Java代碼調用時啟動一個虛擬上專用的JVM,後續的用戶可以使用這一已經存在的支持Java的會話期。
事實上,所有會話共享同一JVM代碼並保持"僅靜態"的私有狀態,而垃圾則收集在單個對話期空間內,從而為各個Java對話期提供了和SQL操作相同的對話期隔離和數據完整性能力。這裡,不需要為了數據完整性而進行單獨的Java支持的過程。這一基於對話期的結構提供了較小的內存占用率,並使OracleJVM具有與Oracle數據庫一樣的線性SMP可伸縮性。
創建Java存儲過程
要將Java方法轉換為Java存儲過程需要幾個步驟,包括:用loadjava實用程序將Java類加載到數據庫中,利用調用規范(Call Spec)發布Java方法,將Java方法、參數類型和返回類型映射到其SQL的對應部分。下面部分說明如何完成這些步驟。
我將使用一個簡單的Hello類,它有一個方法Hello.world(),返回字符串"Hello world":
- public class Hello { public static String world () { return "Hello world"; } }
LoadJava 實用程序
Loadjava是加載Java源文件、Java類文件和Java資源文件的實用程序,它可以用來驗證字節碼,並將Java類和JAR文件布置到數據庫中。它既可以通過命令行調用,也可以通過包含於DBMS_JAVA類中的loadJava()方法調用。為了加載我們的Hello.class示例,輸入:
- loadJava -user scott/tiger Hello.class
從Oracle9i版本2開始,loadjava允許通過為包含在被處理的類中的方法創建相應的Call Specs來自動將Java類發布為存儲過程。Oracle為開發、測試、調試和布置Java存儲過程提供了Oracle9i JDeveloper。
- The Resolver Spec
基於JDK的JVM在列於CLASSPATH中的目錄中查找類引用,並對其進行解析。因為Oracle數據庫類存在於數據庫模式中,所以OracleJVM利用數據庫解析器(resolver)通過列於Resolver Spec中的模式查找並解析類引用。
與CLASSPATH不同(CLASSPATH可以應用於所有的類),Resover Spec根據每類的情況進行應用。缺省解析器首先在加載類的模式中搜尋類,然後在公共同義詞(public synonyms)中搜索。
- loadJava -resolve
你可能需要指定不同的解析器,也可以在使用loadJava時強制進行解析,從而在布置時確定可能在以後運行時發生的任何問題。
- loadJava -resolve -resolver "((* SCOTT) (foo/bar/* OTHERS) (* PUBLIC))"
Call Spec和存儲過程調用
為了從SQL中調用Java方法(以及從PL/SQl和JDBC中調用),必須首先通過Call Spec發布公共靜態方法,它為SQL定義方法采用的參數以及返回的SQL類型。