用PL/SQL和Java開發(fā)Oracle8i應(yīng)用程序

字號:

用PL/SQL和Java開發(fā)Oracle8 i應(yīng)用程序
    隨著Oracle8i的發(fā)布,Oracle 在數(shù)據(jù)庫里支持了二種主要的編程語言??PL/SQL和Java。今天,Oracle的許多客戶既使用PL/SQL建立數(shù)據(jù)庫應(yīng)用程序,也使用Java建立數(shù)據(jù)庫應(yīng)用程序。既然存在二種數(shù)據(jù)庫編程語言,那么就有一個很自然的問題:建立Oracle8i應(yīng)用程序時,PL/SQL和Java 哪一個更好?
    我們來快速地回顧一下,PL/SQL給Oracle數(shù)據(jù)庫開發(fā)人員提供了強大的功能,包括:高性能、易使用、無縫地與SQL結(jié)合,以及強壯性?,F(xiàn)在,PL/SQL依舊是一個成熟的開發(fā)數(shù)據(jù)庫應(yīng)用程序的過程性語言,而且是建立SQL密集型和數(shù)據(jù)密集型應(yīng)用程序的理想語言。隨著Oracle8i的推出,Oracle 在數(shù)據(jù)庫里引入了Java,給這種十分流行的通用語言提供了強壯的、大規(guī)模的平臺。
    利用企業(yè)JavaBean和CORBA,可以用Java開發(fā)多層、面向組件的應(yīng)用程序;也可以用Java開發(fā)傳統(tǒng)的數(shù)據(jù)庫存儲過程。Oracle8i 提供了多種特性,可以簡化用PL/SQL和Java建立應(yīng)用程序的過程,而且可以容易地把二種語言編寫的應(yīng)用程序組合起來。
    這份白皮書,提供了有關(guān)Oracle8i中PL/SQL和Java特性的技術(shù)概述,并就如何利用它們建立應(yīng)用程序提供了實際可行的指導(dǎo)。白皮書分成四個部分:由于許多Oracle 客戶都有現(xiàn)存的PL/SQL應(yīng)用程序,所以,我們開始時,先描述如何現(xiàn)有的PL/SQL程序與Java組合,擴展現(xiàn)有PL/SQL程序;然后,我們描述二種語言里共有的應(yīng)用程序編程特性,解釋如何把PL/SQL和Java共同使用;在第三部分,描述怎樣利用PL/SQL和Java 建立應(yīng)用程序才算(例如:什么時候用PL/SQL最合適,什么時候用Java最合適);最后,我們討論一些真實的例子,實際演示Oracle的客戶們目前在Oracle8i里是如何使用PL/SQL和Java的。
    用PL/SQL和JAVA建立應(yīng)用程序
    開始,我們首先看一下?lián)碛蠵L/SQL應(yīng)用程序的客戶的場景:客戶們想在服務(wù)器里增加新的Java代碼,從而擴充原有的PL/SQL應(yīng)用程序。有三個特別的問題需要考慮:第一,Oracle8i里支持的主要存儲過程類型是什么,可以用什么途徑調(diào)用它們;第二,Java在Oracle8i里如何工作,Java如何同PL/SQL互操作;第三,Oracle8i 服務(wù)器如何處理PL/SQL和Java之間的名稱解析。在整個白皮書里, “Java”這個單詞,既指標準的Java,也指SQLJ (Java里的嵌入SQL),只有在明確地表明討論不同概念時,才表示不同的意思。
    Oracle8i中存儲過程的類型
    Oracle8i支持的存儲過程類型有幾種?Oracle8i 支持四種不同類型的存儲過程??用PL/SQL或Java,都可以實現(xiàn)全部四種類型的存儲過程。這四種存儲過程類型是:
    存儲過程??存儲過程允許客戶用任意商業(yè)邏輯擴展SQL??蛻粲妹Q調(diào)用存儲過程,可以在SQL、PL/SQL包、以及“”位置上調(diào)用存儲過程。
    存儲函數(shù)??存儲函數(shù)實質(zhì)上與存儲過程相同,不同之處在于存儲函數(shù)向調(diào)用者返回值??梢杂妹Q調(diào)用存儲函數(shù),也可以在SQL、PL/SQL包、以及“”位置上調(diào)用存儲函數(shù)。
    數(shù)據(jù)庫觸發(fā)器??觸發(fā)器是與特定的表和視圖關(guān)聯(lián)的商業(yè)規(guī)則,修改對表或視圖時,SQL自動調(diào)用觸發(fā)器。Oracle8i 提供了幾種類型的觸發(fā)器:在SQLDML語句執(zhí)行之前或之后激發(fā)的觸發(fā)器;在每一行更新之前或之后激發(fā)的觸發(fā)器;事件觸發(fā)器(例如:登錄、退出、DDL語句、數(shù)據(jù)庫啟動或關(guān)閉等的觸發(fā)器);替代(instead-of)觸發(fā)器。所有這些觸發(fā)器類型,都可以用PL/SQL或Java編寫。
    對象類型方法?? Oracle8 ™ 發(fā)行版8.0和Oracle8i提供了用SQL定義復(fù)合數(shù)據(jù)類型的能力。這些對象類型的方法,可以用Java實現(xiàn),也可用PL/SQL實現(xiàn)。例如,可以用SQL定義一個訂單對象類型purchase_order_t,如下所示:
    CREATE TYPE purchase_order_t AS OBJECT (
    pono NUMBER,
    custref REF customer_info_t,
    orderdate DATE,
    shipdate DATE,
    line_item_list line_item_list_t,
    shiptoaddr address_t,
    MEMBER FUNCTION
    total_value RETURN NUMBER,
    ) ;
    然后實現(xiàn)這個對象類型的方法 …
    CREATE OR REPLACE TYPE BODY purchase_order_t AS
    MEMBER FUNCTION total_value RETURN NUMBER IS
    i INTEGER;
    stock stock_info_t;
    line_item line_item_t;
    total NUMBER := 0;
    cost NUMBER;
    BEGIN
    // 在這里插入具體的PL/SQL代碼或者譯Java存儲過程的調(diào)用。
    END;
    在Oracle 8i 里,這四種存儲程序類型的每一種,都可以從不同的調(diào)用環(huán)境調(diào)用,這些調(diào)用環(huán)境是:
    SQL語句??可以在任何SQL語句內(nèi)部調(diào)用函數(shù)。
    CALL語法??使用CALL語句,可以在調(diào)用過程和函數(shù)。CALL是隨Oracle8i新引進的語法。
    PL/SQL塊、子程序、包??可以在PL/SQL子程序、包或匿名塊里調(diào)用它們。請注意:Java存儲程序自己可以在匿名的BEGIN … END 塊內(nèi)被調(diào)用。
    觸發(fā)器的隱式調(diào)用??最后,PL/SQL或Java存儲過程可以在觸發(fā)器執(zhí)行的時候,隱式地被調(diào)用。
    把JAVA與現(xiàn)存的PL/SQL程序結(jié)合
    要想理解如何才能把Java 應(yīng)用程序和現(xiàn)有的PL/SQL存儲過程結(jié)合起來,我們首先要理解開發(fā)Java存儲過程的三個步驟:
    第一步:編寫Java 存儲過程:第一步是編寫要做成存儲過程的Java程序。可以用標準的Java編寫,也可以用SQLJ編寫?因為存儲過程通常都是SQL密集型的,所以用SQLJ編寫存儲過程,是一個效率較高的方法。
    public class Foo {
    public static String prependHello(String tail) {
    return "Hello " + tail;}}
    第二步:步署、發(fā)布存儲過程:用Java開發(fā)工具編寫完Java程序后,要把它裝載進Oracle8i。要用Oracle提供的loadjava命令行工具,以源文件、二進制文件、.class類文件、Java .jar歸檔文件的形式,把Java程序裝載進Oracle8i中的目標數(shù)據(jù)庫大綱。Loadjava是一個Java程序,它用Oracle的JDBC驅(qū)動程序連接服務(wù)器,自動把一組Java程序裝載進服務(wù)器。(還可以使用CREATE JAVA這個工具,它是SQL*Plus的SQLDDL命令)
    >loadjava -user scott/tiger@oudelsrv-1:5521:ORCL Foo.class
    命令執(zhí)行之后,會把類foo的方法裝入scott的大綱(請參閱第后面有關(guān)Java、SQL和PL/SQL名稱的內(nèi)容,了解命名空間解析的問題)。下一步是,把方法登記到SQL上。這一步為什么是必不可少的呢?如果只用PL/SQL,就沒有必要顯式地把PL/SQL過程登記到SQL上?對SQL來說,每個PL/SQL過程自動就是可見的。反之,在使用Java的時候,所有的Java方法對SQL來說都是不可見的?要讓一個Java方法能夠作為存儲過程,在SQL里調(diào)用它,就必須顯式地把它“發(fā)布”到SQL當中。Java 類和方法不會自動地發(fā)布到數(shù)據(jù)字典、SQL和PL/SQL里,原因有二:
    Java應(yīng)用程序里的大多數(shù)方法,通常是由其它Java程序調(diào)用;而且Java到Java的調(diào)用,發(fā)生在Java虛擬機環(huán)境里,沒有必要暴露給SQL。
    SQL編譯器需要有關(guān)SQL數(shù)據(jù)類型到Java數(shù)據(jù)類型如何映射參數(shù)的指導(dǎo),還需要正確重載調(diào)用的信息,以便給出與原始實際參數(shù)值對應(yīng)的SQL數(shù)據(jù)類型。這需要開發(fā)人員的干預(yù),所以只有某些Java方法需要在SQL和PL/SQL里調(diào)用。