利用Java存儲過程溝通SQL
XML
Java
J
EE和Web服務
存儲過程(stored procedure)允許將運行於數據庫層中的持久性邏輯與運行於中間層中的商務邏輯有效地分離開來
這種分離可以降低整個應用程序的復雜性
並提供其重用性
安全性
性能和可伸縮性
但是
妨礙存儲過程廣泛采用的一個主要障礙是不同數據庫廠商使用各種專有的
且依賴於數據庫的實現語言
使用基於Java的存儲過程可以解決這一問題
Oracle已經實現了ANSI標准
這些標准規定了從SQL中將靜態Java方法作為過程或函數進行調用的能力
這種實現被簡單地稱作
Java存儲過程
在本文中
你將了解基於Java的存儲過程如何幫助簡化商務邏輯
提高其性能
並擴展數據庫的功能
本文將介紹Oracle如何在數據庫內啟用基於Java的存儲過程
還會介紹Java存儲過程如何訪問數據
以及如何創建基本Java存儲過程
選擇PL/SQL還是Java 在考慮Oracle存儲過程時
你可能會想到PL/SQL
不過
從Oracle
i開始
Oracle已經在數據庫中支持Java
從而為存儲過程提供了不同於PL/SQL的開放式和可移植的方法
我可以聽到
$
問題
我如何在PL/SQL和Java之間做出選擇?我是否應當忘記已經學習的所有PL/SQL相關知識
而變為一個Java天地的新手?
兩種語言都適用於數據庫編程
都有自己的優點和弱點
在決定選擇哪一種語言時
可以參考下面根據經驗得出的通用規則
對於要求與SQL進行無縫集成的數據庫中心來說則邏輯使用PL/SQL
從而完成對數據庫對象
類型和特性的訪問
出於與數據庫的無關性考慮時
可以選擇Java作為開放式的語言來取代PL/SQL
同時也為了集成和溝通SQL
XML
J
EE和Web服務等各個領域
OralceJVM使得Java可以運行在數據庫中 從Oracle
i版本
(Oralce
)開始
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
從Oracle
i版本
開始
loadjava允許通過為包含在被處理的類中的方法創建相應的Call Specs來自動將Java類發布為存儲過程
Oracle為開發
測試
調試和布置Java存儲過程提供了Oracle
i JDeveloper
The Resolver Spec
基於JDK的JVM在列於CLASSPATH中的目錄中查找類引用
並對其進行解析
因為Oracle數據庫類存在於數據庫模式中
所以OracleJVM利用數據庫解析器(resolver)通過列於Resolver Spec中的模式查找並解析類引用
與CLASSPATH不同(CLASSPATH可以應用於所有的類)
Resover Spec根據每類的情況進行應用
缺省解析器首先在加載類的模式中搜尋類
然後在公共同義詞(public synonyms)中搜索
loadjava
resolve <myclass>
你可能需要指定不同的解析器
也可以在使用loadjava時強制進行解析
從而在布置時確定可能在以後運行時發生的任何問題
loadjava
resolve
resolver
((* SCOTT) (foo/bar/* OTHERS)
(* PUBLIC))
Call Spec和存儲過程調用 為了從SQL中調用Java方法(以及從PL/SQl和JDBC中調用)
必須首先通過Call Spec發布公共靜態方法
它為SQL定義方法采用的參數以及返回的SQL類型
在我們的例子中
我們將利用SQL*Plus連接到數據庫
並為Hello
world()定義一個頂級Call Spec
SQL> connect scott/tiger
SQL> create or replace function helloworld return
VARCHAR
as language java name
Hello
world () return
java
lang
String
;
/
Function created
可以像下面這樣調用Java存儲過程
SQL> variable myString varchar
[
];
SQL> call helloworld() into :myString;
Call completed
SQL> print myString;
MYSTRING
Hello world
Java存儲過程可以通過其Call Spec從以下各項中進行調用
SQL DML語句(INSERT
UPDATE
DELETE
SELECT
CALL
EXPLAIN PLAN
LOCK TABLE和MERGE)
PL/SQL塊
子程序
程序包以及數據庫觸發器
Call Spec的美妙之處在於存儲過程實現可以從PL/SQL轉換為Java
反之亦可
這一點對於請求者是透明的
Call Spec從實現語言中(PL/SQL或Java)中抽象出調用界面
因而使之能夠在原有應用程序和新的基於Java/J
EE的應用程序之間共享商務邏輯
但是
在從Java客戶程序調用在數據庫駐留的Java類時
你可能不希望通過PL/SQL包裝器(wrapper)
在以後的版本中
Oracle計劃提供一種機制
它可以使開發人員略過Call Spec
高級數據訪問控制 Java存儲過程可用於控制和限制對Oracle數據的訪問
其方法是只允許用戶通過存儲過程管理數據
而存儲過程在其調用者的權限內執行
而不能對表本身進行訪問
例如
你可以在特定時間內禁止更新數據
或者使管理者只具有查詢工資數據的權利
而不能進行更新
或者記錄所有的訪問並通知某一安全機構
原有應用程序與JEE應用程序之間的數據邏輯共享 因為原有應用程序與J
EE應用程序都通過Call Spec調用存儲過程
所以J
EE和非J
EE應用程序可以共享相同的數據邏輯
由於有了Call Spec
所以不用考慮所用的是何種實現語言(無論是PL/SQL還是Java)
該數據邏輯都可以共享
為BMP實體Bean自動生成主關鍵字 在對EJB實體bean應用BMP時
一個bean實例可以由自動生成的與新插入的數據相關聯的主關鍵字惟一確定
它是ejbCreate()的返回值
可以利用一個插入相應數據的存儲過程在一個數據庫操作中檢索ejbCeater()中的該值
並檢索或計算主關鍵字
作為另一種方法
也可以利用JDBC
的RETURN_GENERATED_KEYS特性
以一個SQL語句插入該數據並檢索相應的關鍵字(或ROWID)
但是
存儲過程方法在各個JDBC驅動器版本和數據庫之間更具可移植性
可以用以下三個步驟實現這一模式
創建一個Java存儲過程
在公共GenPk類中定義一個公共靜態Java方法insertAccount()
此方法將插入數據
計算惟一的關鍵字(通過發出一個序列號)
並返回計算出的關鍵字作為主關鍵字
定義Call Spec
CREATE OR REPLACE PROCEDURE insertAccount(owner IN
varchar
bal IN number
newid OUT number)
AS LANGUAGE JAVA NAME
GenPK
insertAccount(
java
lang
String [])
;
/
在ejbCreate()內調用存儲過程
Public AccountPK ejbCreate(String ownerName
int balance) throws CreateException
{
try {
CallableStatement call = conn
prepareCall{
{call insertAccount(?
?
?)}
};
return new AccountPK(accountID);
}
}
為CMP實體Bean定制主關鍵字查找器 查找器方法(Finder methods)用於檢索已存在的EJB實體bean實例
主關鍵字查找器使你能夠檢索惟一標識的EJB實例
對於CMP實體bean
EJB容器根據聲明描述
自動生成主關鍵字查找器findByPrimaryKey()方法
但是
在某些情況下
可能需要更多的控制
例如可能需要專門的查找器
如findByStoredProcKey()
在這些情況下
你可以結合使用Java存儲過程和對象關系框架(如Oracle
i應用服務器[Oracle
iAS] TopLink)來實現定制的主關鍵字查找器方法
在將EJB查找器定義為REDIRECT或NAMED查找器後
TopLink將生成一個SQL查詢用於檢索bean實例
數據驅動的EJB調用 在數據驅動體系結構中
商務邏輯調用可以作為數據庫操作(如插入
更新或刪除)的結果來觸發
實現該數據邏輯的Java存儲過程可以被聲明為數據庫觸發器
用以調用運行於中間層J
EE應用服務器的EJB
EJB的調用既可以采用J
EE
兼容的服務器通過Interoperable Inter
ORB Protocol(IIOP)標准遠程方法調用(remote method invocation
RMI)
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25942.html