程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> DB2數據庫 >> DB2教程 >> 應用開發: Java:熱力不斷

應用開發: Java:熱力不斷

編輯:DB2教程

到目前為止,也許您已經讀過很多關於 DB2 9 for Linux, Unix, and Windows(以前的代號為 “Viper”)中的混合型引擎的內容,這種混合型引擎便於 XML 數據和關系數據的集成。也許您還閱讀過關於能加快應用程序開發的 DB2 9 特性的內容。在本文中,我將介紹對於開發 Java 應用程序而言比較重要的一些新特性。

Java 5.x 支持

DB2 9 現在在很多平台上支持 Java 5.x。Java 5.x 引入了很多新的、增強的特性,包括對 Unicode 增補字符的支持、增強的 FOR 循環、泛型、類型安全的枚舉類型、可變參數等等。在開發用於 DB2 的 Java 應用程序和 Java 例程時,可以利用這些特性。

DB2 Driver for JDBC and SQLJ

在 DB2 9 中,DB2 Driver for JDBC and SQLJ 現在是 Java 應用程序的默認驅動程序。DB2 JDBC Type 2 驅動程序不被推薦,而 DB2 JDBC Type 3 驅動程序已被廢棄。如果您想使用 DB2 Driver for JDBC and SQLJ 作為 Java 例程運行時支持的默認驅動程序,那麼可以將 DB2 注冊表變量設置為 DB2_USE_DB2JCCT2_JROUTINE=ON。(默認情況下這個注冊表變量沒有設置。)

隨 DB2 9 一起發布的增強的 DB2 Driver for JDBC and SQLJ 遵從 JDBC 3.0 規范。這種驅動程序包括對新的 XML 列數據類型、XQuery、新的更新和檢索 XML 列中數據的方法以及帶 XML 參數的存儲過程調用的支持。另外還包括用於注冊 XML 模式和建立受信任連接的新的 DB2 方法。

DB2 9 支持在 JDBC 和 SQLJ 應用程序和例程中使用 XML。IBM Universal JDBC Driver 通過一個 com.ibm.db2.jcc.DB2XML 專用接口,支持在查詢和 Java 應用程序和例程的輸入輸出參數中使用 XML 數據。

應用開發: Java:熱力不斷

目前,JDBC 標准中還不包括本機 XML 類。因此,在 DB2 9 中,XML 列被映射為 Java 字符串、字節數組、流和新的 com.ibm.db2.DB2Xml 類。要插入和更新 XML 列,可以使用表 1 中列出的任意方法名和相應的輸入數據類型。

應用開發: Java:熱力不斷

可以使用字符串、字節數組、流或專用的 com.ibm.db2.jcc.DB2Xml 類型檢索 XML 列中的 XML 數據。可以使用 ResultSet 或 DB2Xml 方法檢索數據。ResultSet 方法與 DB2Xml 方法的不同之處在於,有些 DB2Xml 方法為輸出數據增加了編碼說明。具體地說,DB2Xml.getDB2XmlXXX 方法為輸出數據增加了 XML 聲明,其中包括編碼說明,而 DB2XML.getDB2XXX 方法則沒有。表 2 顯示了方法名稱、相應的輸出數據類型和編碼說明。

讓我們看看在 DB2 SAMPLE 數據庫上運行的一些例子,這個 SAMPLE 數據庫應該以 Unicode 創建,以便這些例子可以存儲 XML 數據。運行這些例子所需的所有腳本和其他文件,已經在安裝 DB2 9 的時候一起安裝在操作系統上。若要將已有的 SAMPLE 數據庫轉換成 Unicode,以便可以使用當前的關系數據和新的 XML 數據例子,請遵循 publib.boulder.ibm.com/infocenter/db2luw/v9/index.JSP?topic=/com.ibm.db2.udb.admin.doc/doc/t0024033.htm 中的說明。

運行例子前的准備工作:

1. 使用 CREATE DATABASE 命令,以 Unicode 創建 DB2 SAMPLE 數據庫:

CREATE DATABASE SAMPLE USING CODESET UTF-8 TERRITORY US

2. 運行 SQLLIB/samples/xml/db2sampl_XML.db2 腳本,從而創建表、插入 XML 數據以及將 XML 模式注冊到 SAMPLE 數據庫中。該腳本通過以下命令將 sqllib/samples/xml/customer.xsd XML 模式注冊到 XML 模式庫(XSR)中:

REGISTER XMLSCHEMA http://posample.org FROM customer.xsd AS customer;
COMPLETE XMLSCHEMA customer;

本節中所有的 XML 例子都訪問 SAMPLE 數據庫中的 Customer 表,其定義如下:

CREATE TABLE CUSTOMER (Cid BIGINT NOT NULL,
Info XML,
History XML)

讓我們從 InsertSelect.Java 應用程序開始。該應用程序:

調用 Java 元數據方法 ResultSetMetaData.getColumnTypeName 獲得 XML 列類型。

將客戶 ID 為 1006(Cid = 1006)的一個新客戶插入到 CUSTOMER 表中,並用 XMLVALIDATE 函數驗證數據:

客戶信息存儲在一個名為 customer1006.XML 的文件中。

customer1006.XML 文件中的數據將被插入到 CUSTOMER 表的 Info 列中。

在插入操作期間,使用 Customer.xsd 驗證 XML 數據。

使用 ResultSet.getObject 和 DB2Xml.getDB2XmlString 方法,通過 XQuery 從 Info XML 列檢索所有客戶姓名。

為簡單起見,在 InsertSelect.Java 中用戶 ID、密碼和連接 URL 都是硬編碼的。

清單 1 顯示了 customer1006.XML 文件。 清單 2 顯示了 InsertSelect.Java 的源代碼,清單 3 則顯示程序的輸出。可以看到,CUSTOMER 表包含兩個 XML 列,即 Info 和 History,驅動程序將 ISO-10646-UCS-2 編碼添加到輸出中,因為我們使用 DB2Xml.getDB2XMLString 方法來檢索字符串。

Java 存儲過程

在 DB2 9 中,還可以返回 XML 數據作為結果集,或者在存儲過程中使用 XML 參數。清單 4 顯示了如何使用 XQuery 檢索 XML 數據,以及如何返回作為 DB2XML 輸出參數的值。這個存儲過程檢索居住在安大略省馬克姆的客戶的信息。

Java 例程類裝載器

如果您熟悉 DB2 環境中的 Java 例程,包括用戶定義函數(UDF)和存儲過程,那麼就會知道,Java 例程的主體是放在數據庫服務器上的一些類中的。用於實現例程的類文件,必須要麼存放在安裝在數據庫中的 JAR 文件中,要麼用操作系統的 CLASSPATH 環境變量指定。

DB2 UDB Version 8 在整個實例中僅支持一個具有給定名稱的 Java 類文件。DB2 類裝載器搜索類和用 CLASSPATH 指定的 JAR 文件,並選擇它碰到的第一個具有被請求名稱的類。如果在不同路徑中存在多個具有相同類名的 Java 存儲過程和不同的 JAR 文件,那麼 DB2 UDB V8 僅裝載一個類,然而對於給定例程而言,這個被裝載的類可能不是它所對應的類。

之所以會產生這樣的沖突,是因為例程的主體通常都存儲在 sqllib/function 目錄中,而一個實例中的所有數據庫都使用這個目錄,而在類解析期間又沒有使用 JAR ID。對於 Java 例程,僅僅將有問題的文件轉移到不同的目錄是不能解決類名沖突的,因為 CLASSPATH 環境變量是在整個實例中使用的。

讓我們來看一個簡單的例子。這個例子中有兩個存儲過程 QUERYSTAFF 和 QUERYORG,它們是在一個名為 Query.java 的文件中實現的。QUERYSTAFF 的源代碼在 Staff/Query.java 中,QUERYORG 的源代碼在 Org/Query.java 中;Staff/Query.java 中實現的一個存儲過程對 DB2 SAMPLE 數據庫中的 STAFF 表執行一個 SELECT 操作,而 Org/Query.Java 中實現的一個存儲過程則是對 DB2 SAMPLE 數據庫中的 ORG 表執行一個 SELECT 操作;每個存儲過程有一個對應的 JAR 文件,它們都被安裝在 SAMPLE 數據庫中。

清單 5 和 清單 6 顯示了這兩個存儲過程的源代碼。它們之間的不同之處已經用粗體標注出來。

CREATE PROCEDURE 語句的語法在 publib.boulder.ibm.com/infocenter/db2luw/v9/index.JSP?topic=/com.ibm.db2.udb.admin.doc/doc/r0008328.htm 中有說明。

在 清單 7 顯示的例子中,首先創建一個 QUERYORG 存儲過程,對應的 EXTERNAL NAME 為 ‘QUERYORG:Query.query’。接著創建一個 QUERYSTAFF 存儲過程,對應的 EXTERNAL NAME 為 ‘QUERYSTAFF:Query.query’。按照這樣的順序創建存儲過程後,DB2 可能會為第二個存儲過程裝載錯誤的類。在這種情況下,當調用 QUERYSTAFF 存儲過程時,會得到意外的結果。

當在 DB2 UDB V8 SAMPLE 數據庫上運行 QUERYSTAFF 過程時,實際上運行的是 QUERYORG。輸出經過了截尾處理,因為 QUERYSTAFF 的輸出參數被定義為 CHAR(9),由於 QUERYORG 的輸出被定義為 CHAR(14),因此前者不足以容納後者。清單 8、9 和 10 演示了這個問題。清單 8 顯示了在 DB2 V8 中 QUERYSTAFF 的不正確的輸出。清單 9 顯示了 QUERYORG 的輸出。清單 10 顯示了 QUERYSTAFF 過程的正確輸出。

之所以會出現這樣的問題,是因為 DB2 V8 會忽略 CREATE PROCEDURE 語句中指定的 JAR ID,而首先找到實現 QUERYORG 過程的 Query.class。然而,當我們調用 QUERYSTAFF 時,我們是想裝載第二個 Query.class,這個類屬於 QUERYSTAFF 過程。

在 DB2 UDB V8 中,對於這個問題有兩種解決辦法:一種辦法是將其中一個受影響的類重命名,使得每個類有一個惟一的類名,另一種辦法是為每個數據庫創建一個不同的實例。

DB2 9 中的 Java 類裝載器

在 DB2 9 中,Java 類裝載器經過了重新設計。現在,每當請求選擇和裝載一個類時,都要提供一個 JAR ID 和類 ID,類裝載器將嘗試在指定 JAR 文件中尋找類;因此,它總是裝載正確的類。此外,如果指定一個 JAR ID,類搜索的性能也將得到提高,因為 DB2 9 只需搜索屬於指定 JAR 文件的類。

在 DB2 9 中,可以使用 CREATE PROCEDURE 語句的 EXTERNAL NAME 子句指定 JAR ID、類 ID 和方法 ID,就像在 DB2 V8 中一樣。當發出 CREATE PROCEDURE 語句時,類和方法不必已經存在。但是,在調用該存儲過程時,類和方法必須已經存在,並能夠被數據庫服務器訪問。否則,就會出現錯誤(SQLSTATE 42884)。如果指定一個 JAR ID,那麼當發出 CREATE PROCEDURE 語句時,該 JAR 文件必須已經存在。如果沒有指定 JAR ID,那麼 DB2 9 就維持 DB2 V8 中那樣的不確定裝載行為。

如果使用 DB2 9,並重復上述步驟來創建和運行 QUERYSTAFF 及 QUERYORG,那麼您將發現,使用不正確的類的問題不復存在了。這是因為 Java 類裝載器現在會考慮 JAR ID。如果在 EXTERNAL NAME 子句中指定 QUERYSTAFF:Query.query,DB2 9 將裝載 sqllib/function/jar/<Schema>/QueryStaff.jar 中的 Query.class,並運行屬於 QueryStaff.jar 的 query() 方法。DB2 9 並不是簡單地裝載它碰到的第一個 Query.class。清單 11 顯示了使用 DB2 9 時的結果。

通過將類文件打包到一個 JAR 文件中,並使用 CREATE PROCEDURE 語句的 EXTERNAL NAME 子句指定 JAR ID,盡量利用新的、增強的類裝載器。如果 Java 例程已經在一個 JAR 文件中,但是沒有在 CREATE PROCEDURE 語句中指定 JAR ID,那麼可以使用 ALTER PROCEDURE 或 ALTER FUNCTION 語句增加或修改 JAR ID 字段。

進一步學習

在本文中,我介紹了 DB2 9 的很多 Java 應用程序支持特性。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved