關系數據庫在您的電子商務應用中一定扮演著不可或缺的重要角色。DB2 是您的選擇麼?也許您的系統裡早就部署了 DB2 UDB V7.2 系列軟件;也許您正打算升級您的 DB2 系統到最新的版本;也許您剛剛部署了最新的 DB2 UDB V8.1 系列軟件,並且想更新您之前開發的應用系統。如果您正打算這麼做,那麼這篇文章的話題應該是您所感興趣的。
您的應用系統如果想和 DB2 系統打交道,我想首先需要做的一定是和 DB2 數據庫建立連接並且對數據庫進行各種操作。對於基於 JAVA 平台的應用程序來說,JDBC(Java Database Connectivity)一定是開發人員的首選。它作為 JAVA 編程語言的必備組件,已經成為 JAVA 2 標准版(Java 2,Standard Edition,J2SE)規范的一部分,而 DB2 系統對 JDBC 做了很好的支持。
在您決定遷移您的應用系統的時候,可能並不想直接升級您的DB2系統到最新的版本,這個時候就可能會碰到和我開發中所碰到的相似的情形,即我們需要適應不同版本的 DB2 數據庫同時存在的應用環境,這時我們可能希望應用程序能夠順利地在不同版本的 DB2 數據庫之間遷移而無需做過多的修改。
本文就介紹了為解決這類問題所做的一系列實驗,並且根據實驗結果給開發人員提出了一些建議。
我們討論的范圍限定在使用 JDBC 連接 DB2 UDB V7.2 和 DB2 UDB V8.1 時碰到的問題。這裡實驗環境中的 JDK 版本是 1.3,可能有些開發人員已經嘗試采用 JDK1.4 了,如果開發中碰到一些令人費解的問題,請嘗試改變您的 JDK 版本再做嘗試,這往往就能解決你的問題。
通過本文,讀者可以了解到下面的一些知識:
1. DB2 系統對 JDBC (Java Database Connectivity)的支持
2. DB2 命令行工具 CLP(Command Line Processor)
3. DB2 命令中心(DB2 Command Center)
4. 不同版本 DB2 系統發布的 JDBC 驅動程序彼此的兼容性
我在實驗中使用的軟件系統包括:
1. IBM DB2 UDB V7.2 Enterprise Edition
2. IBM DB2 UDB V7.2 Enterprise Edition FixPack 7
3. IBM DB2 UDB V8.1 Enterprise Server Edition
4. IBM DB2 UDB V8.1 Enterprise Server Edition FixPack 4
5. IBM WSAD V5.0
6. Windows 2000 Server
DB2 與 JDBC 支持
依照 JDBC 規范,有四種類型的 JDBC 驅動程序體系結構:
Type 1:這類驅動程序將 JDBC API 作為到另一個數據訪問 API 的映射來實現,如開放式數據庫連通性(Open Database Connectivity,ODBC)。這類驅動程序通常依賴本機庫,這限制了其可移植性。JDBC-ODBC 橋驅動程序就是 Type 1 驅動程序的最常見的例子。
Type 2:這類驅動程序部分用 Java 編程語言編寫,部分用本機代碼編寫。這些驅動程序使用特定於所連接數據源的本機客戶端庫。同樣,由於使用本機代碼,所以其可移植性受到限制。
Type 3:這類驅動程序使用純 Java 客戶機,並使用獨立於數據庫的協議與中間件服務器通信,然後中間件服務器將客戶機請求傳給數據源。
Type 4:這類驅動程序是純 Java,實現針對特定數據源的網絡協議。客戶機直接連接至數據源。
對於DB2 UDB V7.2來說,它不支持 Type 1 和 Type 4 的驅動程序,但是提供了分別支持 Type 2 和 Type 3 的驅動程序。
示例如下:
兩種驅動程序均隨產品安裝由 db2Java.zip 提供。
COM.ibm.db2.jdbc.app.DB2Driver
這是一種 Type 2 的 JDBC 驅動程序,它通過 DB2 本地客戶機庫的幫助建立和 DB2本地數據庫或是遠程數據庫的連接(事先將遠程數據庫編目到本地)。因此,我們必須在應用系統所在的機器上同時部署 DB2 本地客戶機庫,這也許是它最大的一個不足之處。
使用格式如下:
Driver Name:COM.ibm.db2.jdbc.app.DB2Driver
URL Pattern:jdbc:db2:databasename
databasename: 需要訪問的數據庫名
COM.ibm.db2.jdbc.Net.DB2Driver
這是一種 Type 3 的 JDBC 驅動程序,它通過與一台已經部署了 DB2 本地客戶機庫的機器通信來建立和 DB2 遠程數據庫的連接。
使用格式如下:
Driver Name:COM.ibm.db2.jdbc.Net.DB2Driver
URL Pattern:jdbc:db2:ServerIP:databasename
ServerIP: 需要訪問的數據庫所在機器IP地址
databasename: 需要訪問的數據庫名
(目標DB2系統偵聽該服務於默認端口6789,否則還需要在 URL Pattern 中指定目標端口號)
對於 DB2 UDB V8.1 來說,它仍然不支持 Type 1 的驅動程序。同時,它在 DB2 UDB V8.1的基礎上,新增加了對 Type 4 驅動程序的支持。
示例如下:
DB2 UDB V8.1 仍然支持上面所述 V7.2 支持的兩種驅動程序,隨產品安裝由 db2Java.zip 提供,但具體實現上和 DB2 UDB V7.2 產品發布的包有所不同,所以可能存在下文所要進行實驗驗證的兼容性問題。
除了 COM.ibm.db2.jdbc.app.DB2Driver 之外,DB2 UDB V8.1 還提供了另外一種 Type 2 的驅動程序,隨產品安裝由 db2jcc.jar 提供。其實現包名是 com.ibm.db2.jcc.DB2Driver,在DB2 UDB V8.1 最初的實現中,此驅動程序只用於使用 Type 4 驅動程序體系結構與 DB2 服務器進行直接的 Java 連接,這類驅動程序由於不需要另外部署 DB2 本地客戶機庫以及性能相對較好而收到開發人員的歡迎。自從 DB2 UDB V8.1.2(安裝了 FixPack 2)之後,開發人員還可以在 Type 2 體系結構中使用該驅動程序,以提高本地應用程序的性能。
這裡,兩種驅動程序具有相同的實現類名稱,有兩種不同的方法可以區分 DB2 系統在內部最終會實例化哪個驅動程序:
使用不同的 URL Pattern 來區分兩種不同的驅動程序
Type 2 Driver URL Pattern:jdbc:db2:databasename
這當中 databasename 是需要訪問的數據庫名
Type 4 Driver URL Pattern:jdbc:db2://ServerIP:50000/databasename
這當中 ServerIP 是需要訪問的數據庫所在機器IP地址,databasename 是需要訪問的數據庫名,DB2 服務器會在默認端口 50000 上進行偵聽。
使用連接特性來區分數據庫連接是否會使用 DB2 本地客戶機庫,或者是使用Java 直接連接。
DB2 UDB V8.1 新增加支持的這種 Type 4 驅動程序,常被稱為“通用 JDBC 驅動程序”,是一種與驅動程序類型連通性或目標平台無關的抽象 JDBC 處理器,因此常用於進行分布式和本地 DB2 UDB 訪問。因為“通用 JDBC 驅動程序”獨立於任何特定 JDBC 驅動程序類型連通性或目標平台,所以它在一個 DB2 UDB 驅動程序實例中同時支持所有 JAVA 連通性(Type 4 驅動程序)和基於 JNI 的連通性(Type 2 驅動程序)。該驅動程序可以用於獨立 Java 應用程序或多層應用程序,是開發人員一個不錯的選擇。
兼容性實驗
上文前後介紹了很多種 DB2 系統支持的 JDBC 驅動程序,想必您的應用中已經采用了其中的某一種或幾種,而在遷移您的應用時您一定希望最好不要更改原有的程序。這個要求能辦到麼?如果您的應用中所采用的驅動程序對不同版本的 DB2 系統進行連接的兼容性足夠好,這個要求就一定能辦到。那讓我們帶著這個疑問,來進行下面這個兼容性實驗吧。
實驗環境:
為了完成這個實驗,我部署了兩台機器,就分別命名為 Machine A 和 Machine B 吧。
Machine A 上部署了 DB2 UDB V7.2.7(安裝了 FixPack 7),它可能和您應用環境中的舊版本 DB2 系統很類似;Machine B 上我部署了 DB2 UDB V8.1.4(安裝了 FixPack 4,這是目前公開發布的最新的補丁),這也許和您升級後的最新 DB2 系統相仿。
相應的,在兩台機器上,我都安裝了 DB2 命令行工具(CLP),DB2 控制中心(Control Center),DB2 命令中心(Command Center)等工具以便能夠對 DB2 系統進行配置和監控。
實驗中當需要編寫代碼的時候,我采用的工具是 WSAD V5.0(WebSphere Studio Application Developer),這是個不錯的開發工具。
實驗目的:
我們帶著上文碰到的這個問題來做這個實驗。因此,我們分別采用上文中提及的各種 JDBC驅動程序嘗試建立與 DB2 本地數據庫和遠程數據庫的連接。如果一切順利,這還只是完成了實驗第一步。假設建立數據庫連接成功,我們會緊接著嘗試對這個數據庫進行各種操作,先是測試查詢操作,這是最常見的數據庫操作;然後會是插入,更新,刪除等 DML 操作,它們會改變數據庫中存儲的數據。如果這些都沒有問題的話,我們還需要繼續嘗試諸如新建,修改,刪除數據表等 DDL 操作。
為了增強實驗的比較效果和准確性,我們除了會編寫代碼來進行各種測試,還會使用 DB2 命令行工具(CLP)和 DB2 命令中心(圖形化管理工具)來進行相同的操作,並且就運行結果進行比較。
明確了實驗目的,下面就來開始我們的實驗吧。
實驗過程:
A:實驗的第一步是測試 DB2 UDB 不同版本隨產品發布的 JDBC 驅動程序對該版本自身的兼容性。
這裡我先編寫代碼完成了各項測試目的,一切順利。
然後,我使用 DB2 命令行工具(CLP)來重復這些測試。
可以通過在命令行中鍵入 db2cmd 進入 DB2 CLP,然後在提示符下鍵入 db2,就會進入DB2 CLP 的交互界面。
如下圖:
這個命令行工具可以完成圖形化工具所做的所有管理配置工作,並且可以節省很多內存資源。
實驗中,我們首先需要用命令連接到一個數據庫:
示例如下,在命令行提示符後鍵入
CONNECT TO SAMPLEDBUSER db2adminUSING passWord
該命令表示使用用戶名為 db2admin,密碼為 passWord,連接至數據庫 SAMPLEDB,緊接著會返回連接後的數據庫相關信息。然後就可以在命令行提示符後直接鍵入各種 DDL 或 DML 語句來執行各種操作。
最後,我們還可以使用 DB2 UDB 隨產品發布的一個圖形化管理工具――命令中心(Command Center)來驗證我們的實驗。
可以參照上圖啟動命令中心,其相關操作請參見產品文檔。
B:這一步我們將測試 DB2 UDB 兩個版本中隨產品發布的 Type 2 JDBC 驅動程序連接與其本身不同版本的 DB2 UDB 系統時的兼容性。
在進行這步測試時,由於 Type 2 JDBC 驅動程序是針對本地數據庫開發的,因此我們需要先將遠程數據庫編目(catalog)到本地,再嘗試連接。下面先給出了采用 DB2 命令行工具編目遠程數據庫的例子。
遠程數據庫的相關信息示例如下:
目標數據庫所在機器名:TESTSERVER
目標數據庫所在機器 IP 地址:10.1.1.15
目標數據庫所屬實例名:TESTINSTANCE
目標數據庫名:SAMPLEDB
目標數據庫所在機器操作系統類型:Windows
啟動 DB2 命令行工具
在命令行提示符下鍵入命令:
CATALOG TCPIP NODE TESTSERVERREMOTE 10.1.1.15 SERVER 50000REMOTE_INSTANCE TESTINSTANCEOSTYPE Windows
此命令將 TESTSERVER 這台機器以及其中指定的數據庫實例編目到本地
在命令行提示符下鍵入命令:
CATALOG DATABASE SAMPLEDBAT NODE TESTSERVER
此命令將樣本數據庫 SAMPLEDB 編目到本地
在命令行提示符下鍵入命令:
COMMIT 此命令將上面基本的修改提交給 DB2 系統使之生效。
在命令行提示符下鍵入命令:LIST DB DIRECTORY
通過這個命令你可以查看所有本地的數據庫以及編目到本地的遠程數據庫的信息,以驗證編目是否成功。
編目遠程數據庫之後,我們就可以將其看作是本地數據庫對其進行各種操作。(如果想進一步了解這些命令的更多內容,可以參考 DB2 聯機幫助)
這部分的測試結果比較有趣,在實驗結果中會詳細描述。
C:完成了上一步之後,我們已經有了不少收獲。在這一步中,我們測試了 DB2 UDB 兩個版本中隨產品發布的 Type 3 JDBC 驅動程序連接與其本身不同版本的 DB2 UDB 系統時的兼容性。
在這步當中,我們直接采用 COM.ibm.db2.jdbc.Net.DB2Driver 這種網絡 JDBC 驅動程序來嘗試連接遠程數據庫,均以失敗告終。這無論是編寫代碼測試,還是 DB2 命令行工具,或者是 DB2 命令中心,都是令人沮喪的結果,因而這種方式不推薦大家使用。
D:最後這步也許是大家所最關心的,就是 DB2 UDB V8.1 新增支持的 Type 4 JDBC 驅動程序連接 DB2 UDB V7.2 時的兼容性(同時也支持Type 2 體系結構訪問)。
這裡我們將 DB2 UDB V7.2 作為遠程數據庫,采用 Type 4 JDBC 驅動程序直接進行連接,同樣以失敗告終。我們轉而先將其編目到本地,采用該驅動程序的 Type 2 方式進行訪問,其現象與用隨 DB2 UDB V8.1 產品發布的 COM.ibm.db2.jdbc.app.DB2Driver 進行測試的結果類似。
這似乎讓我們對這種新增支持的 JDBC 驅動程序失去了信心,不過不要著急。下文中會給出一種解決方法,能夠使得這種驅動程序順利的實現對 DB2 UDB V7.2 數據庫的連接和各種操作。
附件中給出了測試代碼的框架,請有興趣的讀者自行更改各種 JDBC 驅動程序的包名和 URL 模式以完成各種實驗組合。
實驗結果:
A:對於這一類實驗,我們對實驗結果還是很有信心的,最後的實驗結果也驗證了我們事先的預想。
對於DB2 UDB V7.2
DB2 UDB V7.2本地數據庫 DB2 UDB V7.2遠程數據庫 COM.ibm.db2.jdbc.app.DB2Driver 成功 成功 COM.ibm.db2.jdbc.Net.DB2Driver 成功 成功
對於DB2 UDB V8.1
DB2 UDB V8.1 本地數據庫 DB2 UDB V8.1 遠程數據庫 COM.ibm.db2.jdbc.app.DB2Driver 成功 成功 COM.ibm.db2.jdbc.app.DB2Driver 成功 成功 com.ibm.db2.jcc.DB2Driver(Type 2) 成功 成功 com.ibm.db2.jcc.DB2Driver(Type 4) 成功 成功
這步測試中,編寫代碼,DB2 命令行工具,DB2 命令中心測試結果一致。看來隨產品發布的 JDBC 驅動程序對本產品的支持相當不錯。
B:這類實驗的結果差別還是比較大的,也比較有趣。
DB2 UDB V7.2 遠程數據庫
(編目成本地數據庫)
DB2 UDB V8.1 遠程數據庫(編目成本地數據庫)
COM.ibm.db2.jdbc.app.DB2Driver(隨 DB2 UDB V7.2 產品發布) 無意義 成功 COM.ibm.db2.jdbc.app.DB2Driver(隨 DB2 UDB V8.1 產品發布) 連接成功,其它操作失敗(CLP 除外) 無意義這步實驗需要分兩種情況來分析:
1. 本地端是 DB2 UDB V7.2 系統,遠端是 DB2 UDB V8.1 系統,被編目至本地。
先用 DB2 命令行工具建立連接,進行各項數據庫操作,都沒有問題。
再用 DB2 命令中心重復上面操作,也沒有問題。最後編寫代碼重復上面操作,同樣一切正常。
這個結果讓我們非常滿意。
2. 本地端是 DB2 UDB V8.1 系統,遠端是 DB2 UDB V7.2 系統,被編目至本地。
先用 DB2 命令行工具建立連接,進行各項數據庫操作,一切正常。
再用 DB2 命令中心重復上面操作,數據庫連接正常,但繼續做數據庫操作時,會報錯:SQL0805N 找不到程序包 "NULLID.SYSSH200"。 SQLSTATE=51002,無法繼續。
最後,編寫代碼進行測試,數據庫連接一切正常,能夠獲得 Connection 對象引用,但是一旦進行各種數據庫操作,會報和上面同樣的錯誤。
這個錯誤將和下面實驗 D 碰到的錯誤類似,下文會給出統一的解決方案。
C:這類實驗之前我們猜測成功的可能性不大,最後的結果也驗證了我們的猜測。
DB2 UDB V7.2 遠程數據庫(未編目成本地數據庫) DB2 UDB V8.1 遠程數據庫(未編目成本地數據庫) COM.ibm.db2.jdbc.Net.DB2Driver(DB2 UDB V7.2產品發布) 與A重復 連接失敗 COM.ibm.db2.jdbc.Net.DB2Driver(DB2 UDB V8.1產品發布) 連接失敗 與A重復
經過這步測試,可以認為直接用 COM.ibm.db2.jdbc.Net.DB2Driver 連接不同版本的遠程數據庫是不合適的。
D:開發人員一定對 DB2 UDB V8.1 新增支持的這兩種 JDBC 驅動程序期望值很高,因此這步實驗的結果大家會比較關心。
DB2 UDB V7.2 遠程數據庫(編目成本地數據庫) DB2 UDB V7.2 遠程數據庫(未編目成本地數據庫) com.ibm.db2.jcc.DB2Driver(Type 2) 連接成功,其它操作失敗(CLP 除外) 無意義 com.ibm.db2.jcc.DB2Driver(Type 4) 無意義 連接失敗
通過這步實驗,這種最新支持的 JDBC 驅動程序在兼容低版本上與原有驅動類似。看到這個結果我們有點失望。
其實,這個問題的關鍵在於一些標准 JCC JDBC 程序包沒有和目標數據庫進行綁定,可以手工通過執行下面命令來完成這項工作。
示例如下:
db2jdbcbind -url jdbc:db2://ServerIP:50000/SAMPLEDB -user db2admin -password passWord
使用該命令實現綁定相關程序包之後,我又重復了部分實驗 B 和實驗 D,實驗結果如下:
DB2 UDB V7.2 遠程數據庫(編目成本地數據庫) DB2 UDB V8.1 遠程數據庫(編目成本地數據庫) COM.ibm.db2.jdbc.app.DB2Driver(DB2 UDB V8.1產品發布) 成功 成功
DB2 UDB V7.2 遠程數據庫(編目成本地數據庫) DB2 UDB V7.2 遠程數據庫(未編目成本地數據庫) com.ibm.db2.jcc.DB2Driver(Type 2) 成功 無意義 com.ibm.db2.jcc.DB2Driver(Type 4) 無意義 成功
這同時解決了實驗 B 和實驗 D 中都碰到的問題,讓我們松了一口氣。
實驗結論:
通過上面的實驗,我們就可以得出這樣一些建議。它適用於當您需要在不同版本的DB2系統之間遷移您的數據庫應用的時候。
我們可以基於舊版本的 DB2 系統(如 DB2 UDB V7.2),然後將目標系統(如 DB2 UDB V8.1)編目至本地,使用 COM.ibm.db2.jdbc.app.DB2Driver 進行數據庫連接和操作。
我們也可以基於新版本的 DB2 系統(如 DB2 UDB V8.1),然後將目標系統(如 DB2 UDB V7.2)編目至本地,先手工將相關程序包綁定至目標數據庫系統,再使用 COM.ibm.db2.jdbc.app.DB2Driver 或是 com.ibm.db2.jcc.DB2Driver 進行數據庫連接和操作。
實驗的結果讓我們較為滿意,我們有了不只一種選擇來遷移我們的應用。
注:由於時間和環境的限制,實驗不可能覆蓋所有的 JDBC 特性,而只限於較為常見的數據庫操作。因此,可能在一些特殊情形下上面的實驗結果並不成立,歡迎作進一步的討論和補充。
小結
本文的作者在開發中碰到了 JDBC 數據庫應用在不同版本 DB2 系統之間遷移的問題。帶著這個問題,他進行了一系列實驗,測試了 DB2 UDB V7.2 與 DB2 UDB V8.1 中 JDBC 驅動程序彼此的兼容性,並就存在的問題給出了解決辦法。最後給有類似困惑的開發人員提出了一些建議。
浏覽URL http://www.cncms.com.cn/db2/u372913.Html