小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

使用 SDO 和 JDBC Data Access Service 啟用面向服務(wù)的體系結(jié)構(gòu)

 shaobin0604@163.com 2006-12-18


本文對(duì)隨 IBM? Rational? Application Developer V6 一起提供的數(shù)據(jù)訪(fǎng)問(wèn)服務(wù)(Data Access Services,DAS)進(jìn)行了概述,并對(duì)這些訪(fǎng)問(wèn)服務(wù)在使用服務(wù)數(shù)據(jù)對(duì)象(Service Data Object,SDO)的面向服務(wù)的體系結(jié)構(gòu) (SOA) 中扮演的角色進(jìn)行了說(shuō)明。

引言

IBM Rational Application Developer for WebSphere? Software V6 所包含 JDBC Data Access Services 提供了對(duì)面向服務(wù)的體系結(jié)構(gòu)的持久化層的標(biāo)準(zhǔn)化訪(fǎng)問(wèn)。數(shù)據(jù)訪(fǎng)問(wèn)服務(wù) (DAS) 與服務(wù)數(shù)據(jù)對(duì)象 (SDO) 密切相關(guān),因此要了解 DAS 的概念,首先需要了解一下 SDO。

在本文講述的高級(jí)部分,將給出一個(gè)端到端的示例應(yīng)用程序,該應(yīng)用程序使用適合開(kāi)發(fā)人員和架構(gòu)師使用的 JDBC DAS。該示例使用 XML 對(duì)象關(guān)系映射信息保存對(duì) SDO 對(duì)象圖的更改。(請(qǐng)參閱參考資料,以獲得有關(guān) SDO 的更多信息。)

什么是 SDO?

服務(wù)數(shù)據(jù)對(duì)象(Service Data Objects,SDO)是一項(xiàng)新興標(biāo)準(zhǔn),用于表示企業(yè)應(yīng)用程序中的數(shù)據(jù)。SDO 是信息的容器,設(shè)計(jì)用于提升開(kāi)放標(biāo)準(zhǔn)和互操作性。SDO 提供了在整個(gè)企業(yè)應(yīng)用程序中表示信息的方法,包括表示層、業(yè)務(wù)邏輯層和此類(lèi)層之間的通信,如圖 1 所示。


圖 1. SDO 概述
圖 1. SDO 概述

服務(wù)數(shù)據(jù)對(duì)象的主要特性包括:

  • SDO 可以包含嵌套對(duì)象。此功能稱(chēng)為對(duì)象圖,是一種非常靈活的表示數(shù)據(jù)的方式。例如,圖 2 中的 SDO 就表示一個(gè)有各種產(chǎn)品的多個(gè)訂單的客戶(hù):


    圖 2. SDO 數(shù)據(jù)圖
    圖 2. SDO 數(shù)據(jù)圖
  • SDO 支持 XPath,可以訪(fǎng)問(wèn)其封裝的數(shù)據(jù)。XML 路徑語(yǔ)言 (XPath) 是一項(xiàng)開(kāi)放標(biāo)準(zhǔn),是由 World Wide Web Consortium (W3C) 制定的,用于從 XML 文檔訪(fǎng)問(wèn)數(shù)據(jù)。例如,可以使用以下字符串訪(fǎng)問(wèn)特定的產(chǎn)品:CustomerOrder/Product[name=‘MP3Player‘],其中,CustomerOrder 為 Customer 和 Order 之間定義的關(guān)系。

  • SDO 可以作為 XML 構(gòu)件或 Java? 對(duì)象存在。借助對(duì) XML 的這項(xiàng)透明支持,直接使用 <datagraph> 標(biāo)記作為開(kāi)頭來(lái)傳遞 XML SDO,就可以通過(guò) Web 服務(wù)(或任何 XML 傳輸,如 REST 或 XML-RPC)傳遞 SDO。而且,僅在 SDO v1 中使用更改摘要時(shí),才有必要使用 <datagraph> 標(biāo)記。在其他所有情況下,可以使用任何標(biāo)記。

  • SDO 包含更改摘要。SDO 更改摘要作為所有活動(dòng)的歷史記錄使用,通過(guò)使用此功能,應(yīng)用程序可以將舊數(shù)據(jù)和新數(shù)據(jù)區(qū)分開(kāi)。例如,加入某個(gè)客戶(hù)決定下新訂單。接受訂單的企業(yè)系統(tǒng)由圖 3 中的高級(jí)組件組成。請(qǐng)注意,包含新訂單的 SDO 將從門(mén)戶(hù)服務(wù)器傳遞到后端服務(wù)。如果沒(méi)有更改摘要,后端服務(wù)必須將 SDO 中的所有數(shù)據(jù)放入數(shù)據(jù)庫(kù)。不過(guò),由于可以訪(fǎng)問(wèn) SDO 更改摘要,因此,只需要將新數(shù)據(jù)放入數(shù)據(jù)庫(kù)即可,從而提高后端服務(wù)的效率。此外,門(mén)戶(hù)服務(wù)器可以通過(guò)使用更改摘要來(lái)傳遞更小的 SDO,該 SDO 中僅包含在前端所做的更改。


    圖 3. 更改摘要
    圖 3. 更改摘要
  • SDO 是開(kāi)放標(biāo)準(zhǔn)。SDO 1.0 和 2.0 規(guī)范均是由 BEA? 和 IBM 聯(lián)合發(fā)布的(請(qǐng)參閱參考資料)。任何組織都可以免費(fèi)使用和實(shí)現(xiàn)這些標(biāo)準(zhǔn)。

什么是 DAS?

數(shù)據(jù)訪(fǎng)問(wèn)服務(wù) (Data Access Service) 根據(jù) SDO 1.0 標(biāo)準(zhǔn)保存 SDO。DAS 可以采用任何持久化機(jī)制實(shí)現(xiàn)。例如,Rational Application Developer V6 包括了一個(gè) JDBC DAS 和一個(gè) EJB 實(shí)體 Bean DAS,允許采用標(biāo)準(zhǔn)方式將 SDO 保存到各種后端系統(tǒng),從而提升企業(yè)應(yīng)用程序內(nèi)的互操作性和標(biāo)準(zhǔn)。


圖 4. DAS 概述
圖 4. DAS 概述

DAS 是一項(xiàng)新興的規(guī)范,其標(biāo)準(zhǔn)化進(jìn)程仍在進(jìn)行之中。現(xiàn)在稱(chēng)為 DAS 的新一輪工作就是即將推出的數(shù)據(jù)訪(fǎng)問(wèn)服務(wù) (DAS) 標(biāo)準(zhǔn)??梢詫?DAS 稱(chēng)為 DAS 2.0。DAS 將對(duì) SDO 2.0 規(guī)范形成補(bǔ)充,正在制定之中(DAS 被認(rèn)為處于 SDO 2.0 規(guī)范之外)。





回頁(yè)首


面向服務(wù)的體系結(jié)構(gòu)中的數(shù)據(jù)訪(fǎng)問(wèn)服務(wù)

SDO 數(shù)據(jù)訪(fǎng)問(wèn)服務(wù)非常適合作為 SOA 服務(wù)公開(kāi)。他們提供了一個(gè)標(biāo)準(zhǔn),用于構(gòu)建可以在 SOA 服務(wù)間共享的后端服務(wù)。例如,假如有一個(gè)必須和兩個(gè)不同業(yè)務(wù)進(jìn)行通信的企業(yè)系統(tǒng)。這兩個(gè)業(yè)務(wù)服務(wù)使用完全不同的技術(shù)保存信息。如果傳遞給這些服務(wù)的消息為 SDO,則兩個(gè)服務(wù)都可以使用 DAS,企業(yè)應(yīng)用程序可以將其看作同一個(gè)組織而進(jìn)行處理,如圖 5 中所示。


圖 5. SOA 中的 SDO 數(shù)據(jù)訪(fǎng)問(wèn)服務(wù)
圖 5. SOA 中的 SDO 數(shù)據(jù)訪(fǎng)問(wèn)服務(wù)

DAS 還可以提高 SOA 的可維護(hù)性。實(shí)現(xiàn) SOA 的一個(gè)常見(jiàn)毛病就是會(huì)假設(shè)公開(kāi)服務(wù)總是有好處的。當(dāng)公開(kāi)了服務(wù)時(shí),要更改非常困難——對(duì)于那些向客戶(hù)或公眾公開(kāi)某種功能的服務(wù)更是如此。例如,假設(shè)某家銀行有一項(xiàng)已公開(kāi)了數(shù)年的服務(wù),由于政府法規(guī)的原因,現(xiàn)在必須對(duì)其進(jìn)行更改——在網(wǎng)上傳輸?shù)南⒈仨毥?jīng)過(guò)加密,如圖 6 中所示。


圖 6. SOA 中的 DAS 和可維護(hù)性
圖 6. SOA 中的 DAS 和可維護(hù)性

如果有數(shù)百合作伙伴訪(fǎng)問(wèn)該服務(wù),該銀行不會(huì)輕易更改服務(wù),因?yàn)槠浜献骰锇閷⒉辉倌芘c他們開(kāi)展業(yè)務(wù)。該銀行的最佳選擇可能就是構(gòu)建另一個(gè) 99% 冗余的服務(wù),并盡力說(shuō)服其合作伙伴轉(zhuǎn)而使用新服務(wù)。這將使用大量資源,而所得到的業(yè)務(wù)價(jià)值也有限。

將 SDO 和 DAS 配合使用,可以減緩這類(lèi)問(wèn)題,因?yàn)?SDO 是動(dòng)態(tài)性非常強(qiáng)的消息。如果該銀行使用的是 SDO,則可以直接通知其合作伙伴對(duì)添加的信息進(jìn)行加密,而不會(huì)更改已公開(kāi)的服務(wù)——只需要更改傳遞給該服務(wù)的消息。如果某個(gè)合作伙伴仍然發(fā)送舊 SDO XML 格式的消息,通過(guò)檢查 SDO 的內(nèi)容(并可能與不兼容的業(yè)務(wù)合作伙伴聯(lián)系),銀行的應(yīng)用程序?qū)⒛軌驅(qū)Υ祟?lèi)情況作出判斷,然后按照以前的方式處理此類(lèi)信息。





回頁(yè)首


使用 SDO 數(shù)據(jù)訪(fǎng)問(wèn)服務(wù)的業(yè)務(wù)案例

在現(xiàn)有持久化技術(shù)的基礎(chǔ)上將 SDO 和 DAS 結(jié)合使用,除了 SOA 的好處之外,其業(yè)務(wù)價(jià)值何在呢?請(qǐng)考慮以下管理方面的特征:

  • SDO 是一項(xiàng)開(kāi)放標(biāo)準(zhǔn)。由于 SDO 是一項(xiàng)公開(kāi)的標(biāo)準(zhǔn),因此不會(huì)出現(xiàn)不得不選用某個(gè)供應(yīng)商的情況。截至本文發(fā)布時(shí),BEA、IBM、Versant、Versata 和 XCalia 均推出了 SDO 實(shí)現(xiàn)。同樣,也已計(jì)劃對(duì) SDO 的數(shù)據(jù)訪(fǎng)問(wèn)進(jìn)行標(biāo)準(zhǔn)化。

  • SDO 和 DAS 可以減少業(yè)務(wù)所必須維護(hù)的代碼量。數(shù)據(jù)訪(fǎng)問(wèn)服務(wù)提供了一種標(biāo)準(zhǔn)的方法,用于保存封裝在 SDO 中的信息,而不受后端系統(tǒng)的影響(不管此后端系統(tǒng)是使用 JDBC 訪(fǎng)問(wèn)的關(guān)系數(shù)據(jù)庫(kù)、使用視圖 Bean 訪(fǎng)問(wèn)的 LDAP 服務(wù)器或是具有 DAS 實(shí)現(xiàn)的其他后端系統(tǒng))。實(shí)際上,為了使用異構(gòu)后端系統(tǒng)而編寫(xiě)的自定義代碼與數(shù)據(jù)訪(fǎng)問(wèn)服務(wù)采用標(biāo)準(zhǔn)的方式進(jìn)行了整合。需要維護(hù)的代碼較少,通常可以盡可能減少潛在的缺陷,從而縮短投入市場(chǎng)的時(shí)間和減少風(fēng)險(xiǎn)。

  • 將 SDO 和 DAS 結(jié)合使用,不需要受具體的持久化技術(shù)限制。DAS 不僅使應(yīng)用程序無(wú)需依賴(lài)于數(shù)據(jù)庫(kù)或操作系統(tǒng),而且還使應(yīng)用程序獨(dú)立于整個(gè)持久化技術(shù)。通過(guò)使用多個(gè)數(shù)據(jù)訪(fǎng)問(wèn)服務(wù),應(yīng)用程序可以支持這些中介的基礎(chǔ)持久化機(jī)制,而不用更改業(yè)務(wù)邏輯或呈現(xiàn)邏輯。對(duì)于 IT 環(huán)境復(fù)雜的組織,這樣可以減少成本、整合資產(chǎn),并可以減少將來(lái)進(jìn)行高成本技術(shù)更改的風(fēng)險(xiǎn)。

  • 使用 SDO 和 DAS 有得有失。這兩項(xiàng)均是新興技術(shù),尚處于早期發(fā)布階段。很多數(shù)據(jù)訪(fǎng)問(wèn)服務(wù)可能不支持其他持久化技術(shù)的最先進(jìn)功能(除非 DAS 專(zhuān)門(mén)為支持該技術(shù)而構(gòu)建)。例如,IBM 的 JDBC Data Access Service 就尚不支持 SDO 表群集環(huán)境的分布式緩存。另外,若要充分發(fā)揮 SDO 和 DAS 的潛力,可能需要對(duì)各種新技術(shù)有所了解,包括 Web 服務(wù)、XPath 及 SDO 規(guī)范。對(duì)于開(kāi)發(fā)組織,可以需要進(jìn)行培訓(xùn)。





回頁(yè)首


按部就班,使用 JDBC Data Access Service

本文剩下的部分將給出一個(gè)實(shí)例應(yīng)用程序的實(shí)現(xiàn)。就功能而言,CloseOrderApplication 將使用 Rational Application Developer V6 包含的 JDBC DAS 關(guān)閉客戶(hù)的訂單。該應(yīng)用程序?qū)臄?shù)據(jù)庫(kù)檢索一個(gè) SDO 對(duì)象圖,對(duì)其進(jìn)行更小,然后保存更改。將數(shù)據(jù)庫(kù)架構(gòu)映射到 SDO 對(duì)象圖的元數(shù)據(jù)是使用 XML 編寫(xiě)的。

JDBC DAS 編程模型

圖 7 所示的關(guān)系圖演示了使用 JDBC Data Access Service 開(kāi)發(fā)應(yīng)用程序時(shí)應(yīng)該有用的編程模型。


圖 7. JDBC DAS 編程模型
圖 7. JDBC DAS 編程模型
關(guān)于示例應(yīng)用程序
此示例不僅是試驗(yàn)性的代碼,因?yàn)槠渲袑?shí)現(xiàn)了 JavaEE 最佳實(shí)踐和實(shí)際錯(cuò)誤處理。如果確實(shí)需要利用 JDBC Data Access Service 的代碼(通常不過(guò)寥寥幾行而已),清單 1 和清單 6 無(wú)疑是最為相關(guān)的了。數(shù)據(jù)庫(kù)設(shè)置、JavaEE 數(shù)據(jù)源定義、XML 元數(shù)據(jù)的 JNDI 查詢(xún)以及異常處理均屬于 JavaEE 開(kāi)發(fā)期間要做的工作,而不屬于 SDO JDBC DAS。

在此模型中,JDBC DAS 使用 ConnectionWrapper 對(duì) JDBC Connection 加以包裝,以連接到數(shù)據(jù)存儲(chǔ)區(qū)。使用 MetadataFactory 創(chuàng)建了 Metadata 的實(shí)例。然后使用各種構(gòu)造(如 Tables、Columns 及 Relationships)定義元數(shù)據(jù)。數(shù)據(jù)庫(kù)查詢(xún)的等效項(xiàng)在元數(shù)據(jù)中定義為篩選器。不過(guò),在此示例中,元數(shù)據(jù)、表、列、關(guān)系和篩選器均在元數(shù)據(jù)中定義,且在 XML 映射文檔需要時(shí)透明地創(chuàng)建。(請(qǐng)參閱參考資料,以了解如何如上所示,在運(yùn)行時(shí)使用元數(shù)據(jù) API。)定義了元數(shù)據(jù)后,就會(huì)將其與 ConnectionWrapper 一起使用,以創(chuàng)建 JDBCAccess。中介可以獲取和保存 SDO DataObject 圖。

我們將通過(guò)執(zhí)行以下任務(wù)來(lái)實(shí)現(xiàn)此實(shí)例應(yīng)用程序:

  1. 創(chuàng)建 JaveEE 項(xiàng)目
  2. 設(shè)置數(shù)據(jù)庫(kù)
  3. 定義 XML 元數(shù)據(jù)
  4. 創(chuàng)建方法
  5. 創(chuàng)建 JDBC 連接包裝類(lèi)
  6. 創(chuàng)建 JDBC 中介
  7. 從數(shù)據(jù)庫(kù)檢索 SDO DataObject 圖
  8. 保存 SDO 圖
  9. 關(guān)閉連接
  10. 檢查應(yīng)用程序異常
  11. 使用 Servlet 測(cè)試應(yīng)用程序

示例應(yīng)用程序的先決條件

此示例假設(shè)為 SDO DAS 使用 JavaEE 環(huán)境。不過(guò)并不需要應(yīng)用程序服務(wù)器。IBM JDBC DAS 可以用于任何支持 Java SE 1.3 或更高版本的應(yīng)用程序中。

1. 創(chuàng)建 JavaEE 項(xiàng)目

在 Rational Application Developer 的 J2EE Perspective 中:

  1. 選擇 File => New => Enterprise Application Project。將其命名為 CloseOrder,然后選擇 Finish

  2. 右鍵單擊 CloseOrder,選擇 New => Dynamic Web Project,將其命名為 CloseOrderWeb,然后單擊 Finish

2. 設(shè)置數(shù)據(jù)庫(kù)

圖 8 顯示了示例應(yīng)用程序的數(shù)據(jù)庫(kù)架構(gòu)。其中包含一個(gè) customer 條目和一個(gè)指向 order 條目的外鍵:


圖 8. 數(shù)據(jù)庫(kù)架構(gòu)
圖 8. 數(shù)據(jù)庫(kù)架構(gòu)

請(qǐng)注意,此處假設(shè)管理用戶(hù)名和密碼均為 db2admin。

  1. 啟動(dòng) DB2 命令行處理程序。缺省情況下,可以采用以下方式啟動(dòng)此工具:

    • Linux? 或 UNIX?:
      • 作為數(shù)據(jù)庫(kù)管理員登錄(比如 su db2admin
      • 鍵入 db2 并按 Enter。
    • Windows?:
      • 選擇 Start => All Programs => IBM DB2 => Command Line Tools => Command Line Processor
  2. 使用命令行處理程序執(zhí)行以下代碼:


    清單 1. DB2 命令
    
                                
                                db2 => CREATE DATABASE EXAMPLE
                                db2 => CONNECT TO EXAMPLE USER db2admin USING db2admin
                                db2 => CREATE TABLE CUSTOMER(CUST_ID INTEGER NOT NULL, NAME VARCHAR(250), ORDER_ID INTEGER)
                                db2 => ALTER TABLE CUSTOMER PRIMARY KEY(CUST_ID)
                                db2 => CREATE TABLE ORDER(ORDER_ID INTEGER NOT NULL, STATUS VARCHAR(250), TOTAL INTEGER, CUSTOMER_ID INTEGER)
                                db2 => ALTER TABLE ORDER PRIMARY KEY(ORDER_ID)
                                db2 => INSERT INTO CUSTOMER(NAME, CUST_ID, ORDER_ID) VALUES (‘Roland Barcia‘, 1, 2)
                                db2 => INSERT INTO CUSTOMER(NAME, CUST_ID, ORDER_ID) VALUES (‘Geoffrey Hambrick‘, 2, 1)
                                db2 => INSERT INTO ORDER(ORDER_ID, STATUS, TOTAL, CUSTOMER_ID) VALUES (1, ‘OPEN‘, 88, 1)
                                db2 => INSERT INTO ORDER(ORDER_ID, STATUS, TOTAL, CUSTOMER_ID) VALUES (2, ‘OPEN‘, 188, 5)
                                db2 => ALTER TABLE CUSTOMER FOREIGN KEY(ORDER_ID) REFERENCES ORDER(ORDER_ID)
                                

  3. CloseOrder 示例應(yīng)用程序?qū)?JDBC 數(shù)據(jù)庫(kù)使用 JNDI 上下文引用,以避免硬編碼數(shù)據(jù)庫(kù)連接信息。展開(kāi) CloseOrderWeb,并雙擊 Deployment Descriptor: CloseOrderWeb

  4. 選擇 Reference 選項(xiàng)卡,選擇 Add... => Resourse reference,然后輸入或選擇字段值,如圖 9 中所示。


    圖 9. 數(shù)據(jù)源 JNDI 上下文引用
    圖 9. 數(shù)據(jù)源 JNDI 上下文引用
  5. JNDI name 字段輸入 jdbc/db2/Example,如圖 10 中所示。


    圖 10. 數(shù)據(jù)庫(kù) JNDI 名稱(chēng)
    圖 10. 數(shù)據(jù)庫(kù) JNDI 名稱(chēng)

3. 定義 XML 元數(shù)據(jù)

若要將數(shù)據(jù)架構(gòu)映射到 SDO 數(shù)據(jù)圖,則必須定義中介元數(shù)據(jù)。


圖 11. O/R 映射
圖 11. O/R 映射

可以在運(yùn)行時(shí)使用 com.ibm.websphere.sdo.mediator.jdbc.metadata.Metadata 定義元數(shù)據(jù),圖 7 對(duì)此作了簡(jiǎn)單描述(請(qǐng)參閱參考資料,以獲得關(guān)于在運(yùn)行時(shí)定義元數(shù)據(jù)的文檔)。不過(guò),我們的示例在 XML 中定義元數(shù)據(jù)。示例應(yīng)用程序?qū)⒃獢?shù)據(jù) XML 文件添加到類(lèi)路徑中,從而簡(jiǎn)化打開(kāi)指向該文件的 java.io.InputStream 的過(guò)程,如要求創(chuàng)建中介時(shí)。

  1. 在 Rational Application Developer 中,右鍵單擊 CloseOrderWeb 項(xiàng)目,然后選擇 New => Source Folder。

  2. 輸入 xml 作為文件夾名稱(chēng),然后選擇 Finish

  3. 右鍵單擊 CloseOrderWeb,然后選擇 Java Resources => metadata,再選擇 New => other... => Simple => Folder => Next。

  4. 將文件夾命名為 DAS 并選擇 Finish。

  5. 右鍵單擊 DAS 文件夾,然后采用類(lèi)似的方式創(chuàng)建一個(gè)名為 metadata.xml 的新文件。

  6. 插入以下語(yǔ)句作為其內(nèi)容:


    清單 2. 將元數(shù)據(jù)添加到 XML
    
                                
                                <?xml version="1.0" encoding="ASCII" ?>
                                <Metadata rootTable="CUSTOMER" xmlns:="http:///com/ibm/websphere/wdo/mediator/rdb/metadata.ecore" >
                                <tables name="CUSTOMER">
                                <columns name="CUST_ID" type="int" />
                                <columns name="NAME" type="string" />
                                <columns name="ORDER_ID" type="int" />
                                <primaryKey columns="CUST_ID" />
                                <foreignKeys columns="ORDER_ID" />
                                <queryInfo filter="( CUST_ID = ? )">
                                <filterArguments name="CUST_ID" type="int" />
                                </queryInfo>
                                </tables>
                                <orderBys column="CUSTOMER.NAME" />
                                <tables name="ORDER">
                                <columns name="ORDER_ID" type="int" />
                                <columns name="STATUS" type="string" />
                                <columns name="TOTAL" type="int" />
                                <primaryKey columns="ORDER_ID" />
                                </tables>
                                <relationships name="OWNER" oppositeName="ORDER_RELATION" childKey="CUSTOMER"
                                parentKey="ORDER" exclusive="false" />
                                </Metadata>

    列和主鍵的 O/R 映射應(yīng)當(dāng)較為直觀。請(qǐng)考慮以下對(duì)某些其他元數(shù)據(jù)標(biāo)記的描述:

    • <tables rootTable="CUSTOMER">
      SDO 數(shù)據(jù)對(duì)象圖必須定義訪(fǎng)問(wèn)的根入口點(diǎn)。在此應(yīng)用程序中 customer 就是根對(duì)象。

    • <queryInfo>
      此標(biāo)記定義篩選器。如果未定義篩選器,元數(shù)據(jù)將仍然有效;此時(shí)中介會(huì)將所有的客戶(hù)(以及所有相關(guān)訂單)作為 SDO 數(shù)據(jù)對(duì)象圖返回。此處定義的篩選器將 SDO 圖的返回縮小,使其僅包含與 filterArgument 匹配的客戶(hù)。當(dāng)中介從數(shù)據(jù)庫(kù)檢索此 SDO 圖時(shí),將要求傳入一個(gè)名為 CUST_ID 的 int 類(lèi)型參數(shù)。請(qǐng)注意,該參數(shù)并沒(méi)有設(shè)置 name = "CUST_ID",因?yàn)槠淇赡芘c數(shù)據(jù)庫(kù)列名稱(chēng)不同。

    • <relationships>
      此標(biāo)記定義 CUSTOMER.OPEN_ORDER_ID 的外鍵關(guān)系。在此關(guān)系中,customer 是子項(xiàng),而 order 為父項(xiàng)。"Exclusive" 設(shè)置為 false,以指示中介檢索所有相關(guān)訂單,甚至包括沒(méi)有 customer 引用的 order。如果將其設(shè)置為 true,則僅檢索至少有一個(gè)子 customer 引用的 order 項(xiàng)。

    (如果收到驗(yàn)證錯(cuò)誤“Element or attribute do not match QName”,可以將其忽略。本文是入門(mén)級(jí)的文章,將不在 Rational Application Developer 內(nèi)設(shè)置驗(yàn)證。)

  7. 示例應(yīng)用程序使用 JNDI 上下文引用查詢(xún)?cè)獢?shù)據(jù)文件的位置。這樣,應(yīng)用程序就可以避免對(duì)文件名稱(chēng)進(jìn)行硬編碼了。展開(kāi) CloseOrderWeb,然后雙擊 Deployment Descriptor: CloseOrderWeb。

  8. 選擇 Reference 選項(xiàng)卡,然后選擇 Add... => Resourse reference,并按照?qǐng)D 12 所示填寫(xiě)值。


    圖 12. 元數(shù)據(jù)資源環(huán)境引用
    圖 12. 元數(shù)據(jù)資源環(huán)境引用
  9. 在 JNDI name 字段中輸入 cell/persistent/string/CloseOrderMetadata,如圖 13 所示。


    圖 13. 元數(shù)據(jù) JNDI 名稱(chēng)
    圖 13. 元數(shù)據(jù) JNDI 名稱(chēng)

4. 創(chuàng)建方法

現(xiàn)在已經(jīng)準(zhǔn)備好,可以開(kāi)始開(kāi)發(fā)應(yīng)用程序的代碼了。

  1. 右鍵單擊 CloseOrderWeb 項(xiàng)目,并選擇 New => Class。

  2. 在 package 中輸入 developerworks.sdo.example 并將其命名為 CloseOrderApplication

為了更好地描述該應(yīng)用程序,將在接下來(lái)的每一步對(duì) CloseOrderApplication 類(lèi)的各個(gè)方法單獨(dú)進(jìn)行討論。首先是該類(lèi)的唯一公共方法 closeOrder(),該方法負(fù)責(zé)整個(gè)示例應(yīng)用程序的組織(圖 14)。


圖 14. CloseOrder 示例應(yīng)用程序的事件序列
圖 14. CloseOrder 示例應(yīng)用程序的事件序列

以下方法是應(yīng)用程序的入口點(diǎn),圖 14 顯示的每個(gè)步驟幾乎都由其進(jìn)行組織:


清單 3. closeOrder 方法

                        
                        public void closeOrder(int customerId) {
                        ConnectionWrapper conn =
                        getConnectionWorker("java:comp/env/jdbc/DASDefault "); [1]
                        JDBCAccess mediator =
                        createAccessWorker("java:comp/env/DAS/XMLMetadata ", conn); [2]
                        DataObject order = null;
                        try {
                        order = getOpenOrderWorker(customerId, mediator); [3]
                        } catch (NoCustomer nc) {
                        Logger.warn("CloseOrder app could not find specified customer. [4]
                        Prompting end user to create one or cancel transaction.", nc);
                        // ... code to notify presentation layer would go here ...
                        } catch (OrderNotOpen ono) {
                        Logger.warn("CloseOrder app could not find order associated with
                        given customer. Notifying end user.", ono); [5]
                        // ... same as above ...
                        }
                        order.set("STATUS", "CLOSED"); [6]
                        persistChangesWorker(order, mediator); [7]
                        closeConnectionWorker(conn); [8]
                        }
                        

此方法的主要任務(wù)是:

  1. 獲取 JDBC 連接包裝類(lèi)。
    getConnectionWorker() 代碼詳細(xì)說(shuō)明數(shù)據(jù)庫(kù)如何連接。輔助方法需要 JDBC 的 JNDI 上下文引用。

  2. 創(chuàng)建訪(fǎng)問(wèn)。
    輔助方法需要 ConnectionWrapper 和對(duì) metadata.xml 的 JNDI 上下文引用。

  3. 獲取客戶(hù)的開(kāi)放訂單。
    輔助方法使用中介獲取 SDO 對(duì)象圖,遍歷到與根 customer 項(xiàng)相關(guān)的 order,然后將其返回。

  4. 處理無(wú)客戶(hù)的異常情況。
    獲取開(kāi)放訂單的輔助方法可能引發(fā) NoCustomer 異常。除了記錄此情況并通知表示層之外(使用 closeOrder() 進(jìn)行),典型的異常處理還可能包括使用新連接重試,或嘗試采用名稱(chēng)替代 ID 進(jìn)行查找。

  5. 處理無(wú)開(kāi)放訂單的異常情況。
    獲取開(kāi)放訂單的輔助方法可能引發(fā) OrderNotOpen 異常。對(duì)此的恰當(dāng)異常處理由讀者自行完成。

  6. 關(guān)閉訂單。
    修改 order SDO DataObject 的狀態(tài)字符串。

  7. 保存訂單。
    將 order SDO DataObject 保存到數(shù)據(jù)庫(kù)。

  8. 關(guān)閉連接。
    關(guān)閉連接。

5. 創(chuàng)建 JDBC 連接包裝類(lèi)

以下代碼示例包含創(chuàng)建數(shù)據(jù)庫(kù)連接的輔助方法。此方法完成了圖 14 所示序列的步驟 (A) 和 (B) 的工作。


清單 4. getConnectionWorker 方法

                        
                        private ConnectionWrapper getConnectionWorker(String ctxRef) {
                        Connection conn = null;
                        try {
                        InitialContext ctx = new InitialContext();
                        DataSource ds = (DataSource) ctx.lookup(ctxRef);
                        conn = ds.getConnection();
                        conn.setAutoCommit(false);
                        conn.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
                        return ConnectionWrapperFactoryImpl.soleInstance.createConnectionWrapper(conn);
                        } catch (NamingException ne) {
                        throw new CloseOrderRuntime("CloseOrder could not lookup jdbc string
                        binding: "+ctxRef, ne);
                        } catch (SQLException sqle) {
                        throw new
                        CloseOrderRuntime("CloseOrder failed to make database connection", sqle);
                        }
                        }
                        

此方法的內(nèi)容對(duì)于具有 JDBC 經(jīng)驗(yàn)的 JavaEE 開(kāi)發(fā)人員非常簡(jiǎn)單。唯一特定于 JDBC DAS 代碼是從 ConnectionWrapperFactory 創(chuàng)建 ConnectionWrapper。請(qǐng)注意,此處使用了一個(gè)泛型運(yùn)行時(shí)異常重新引發(fā)假定將由 JavaEE 應(yīng)用程序中更高層處理的異常。

6. 創(chuàng)建 JDBC 中介

以下代碼示例包含創(chuàng)建中介的輔助方法。此方法完成了圖 14 所示序列的步驟 (C) 和 (D) 的工作。


清單 5. createAccessWorker 方法

                        
                        private JDBCAccess createAccessWorker(String ctxRef, ConnectionWrapper conn) {
                        JDBCAccess mediator = null;
                        String xmlPath = null;
                        try {
                        InitialContext ctx = new InitialContext();
                        xmlPath = (String) ctx.lookup(ctxRef); <b>[1]</b>
                        InputStream is = getClass().getClassLoader().getResourceAsStream(xmlPath); <b>[2]</b>
                        mediator = JDBCAccessFactory.soleInstance.createAccess(is, conn); <b>[3]</b>
                        } catch (NamingException ne) { <b>[4]</b>
                        throw new CloseOrderRuntime("CloseOrder could not lookup metadata string
                        binding: "+ctxRef, ne);
                        } catch (FileNotFoundException fnfe) {
                        throw new CloseOrderRuntime("CloseOrder app cannot find: "+xmlPath, fnfe);
                        } catch (IOException ioe) {
                        throw new CloseOrderRuntime("CloseOrder app has filesystem error", ioe);
                        } catch (AccessException me) {
                        throw new CloseOrderRuntime("Metadata inside "+xmlPath+" is invalid.", me);
                        }
                        return mediator;
                        }
                        

此方法的主要任務(wù)是:

  1. 使用 JNDI 上下文引用獲取文件名。
    采用與查詢(xún) JDBC 數(shù)據(jù)源類(lèi)似的方法檢索 XML 元數(shù)據(jù)文件名。

  2. 創(chuàng)建文件流
    使用文件名創(chuàng)建指向 XML 元數(shù)據(jù)文件的常規(guī) java.io.InputStream。

  3. 創(chuàng)建 JDBC 訪(fǎng)問(wèn)。
    使用 JDBCAccessFactory,并將文件流和數(shù)據(jù)庫(kù)連接包裝類(lèi)作為參數(shù),以創(chuàng)建中介。

  4. 處理異常。
    此處也是使用一個(gè)泛型運(yùn)行時(shí)異常處理各種異常。

7. 從數(shù)據(jù)庫(kù)檢索 SDO DataObject 圖

以下代碼片段包含了從數(shù)據(jù)庫(kù)檢索 SDO 對(duì)象圖并返回客戶(hù)的開(kāi)放訂單的輔助方法。此方法完成圖 14 所示序列中的步驟 (E) 的工作。


清單 6. getOpenOrderWorker 方法

                        
                        private DataObject getOpenOrderWorker(int customerId, JDBCAccess mediator) throws NoCustomer, OrderNotOpen {
                        DataObject graph = null;
                        try {
                        DataObject param = mediator.getParameterDataObject();
                        param.setInt("CUST_ID", customerId); [1]
                        graph = mediator.getGraph(param); [2]
                        }
                        catch(AccessException me) {
                        throw new CloseOrderRuntime("CloseOrder app failed to get customer graph from
                        mediator. CUST_ID="+customerId, me);
                        }
                        List cList = graph.getList("CUSTOMER"); [3]
                        if(cList.size() == 0) {
                        throw new NoCustomer("CloseOrder app could not find customer for
                        CUST_ID="+customerId);
                        }
                        DataObject customer = graph.getDataObject("CUSTOMER.0"); [4]
                        if(customer.getInt("ORDER_ID") == 0 || graph.getList("ORDER").size() != 1) {
                        throw new OrderNotOpen("CloseOrder app did not find an open [5]
                        order for customer with CUST_ID="+customerId);
                        }
                        return customer.getDataObject("ORDER_RELATION"); [6]
                        }
                        

此方法的主要任務(wù)是:

  1. 創(chuàng)建參數(shù)。
    創(chuàng)建一個(gè)名為 CUST_ID 的參數(shù),并將其設(shè)置為 customerId。此參數(shù)在篩選器中使用,以將 SDO 圖限制為僅包含具有元數(shù)據(jù) XML 中指定的特定 ID 的客戶(hù)。

  2. 獲取 SDO DataObject 圖。
    使用步驟 1 中構(gòu)造的參數(shù)對(duì)中介調(diào)用 getGraph 方法。此圖中應(yīng)包含客戶(hù)及其相關(guān)訂單。

  3. 檢查客戶(hù)是否存在。
    getList("CUSTOMER") 方法返回 SDO 圖中所有客戶(hù)數(shù)據(jù)對(duì)象的列表。如果大小為零,則將引發(fā) NoCustomer 應(yīng)用程序異常。

  4. 獲取客戶(hù)。
    從 SDO 圖獲取客戶(hù)。請(qǐng)注意,追加到 CUSTOMER.0 的零是必需的,用以指示要檢索 customer 列表的哪個(gè)元素(在此例中,列表中僅有一個(gè)客戶(hù))。

  5. 檢查是否存在開(kāi)放訂單。
    如果訂單不是開(kāi)放狀態(tài),則不能對(duì)其進(jìn)行關(guān)閉操作。將檢查 OPEN_ORDER_ID 外鍵,還將檢查 order DataObject 列表是否為非零。

  6. 返回開(kāi)放訂單。
    通過(guò)遍歷元數(shù)據(jù)中定義的關(guān)系,從 customer 子圖檢索開(kāi)放訂單。

8. 保存 SDO 圖

以下代碼示例包含保存已更新 SDO DataObject 圖的輔助方法。此方法完成了圖 14 所示序列的步驟 (G) 的工作。


清單 7. persistChangeWorker method

                        
                        private void persistChangesWorker(DataObject graph, JDBCAccess mediator) {
                        try {
                        mediator.applyChanges(graph);
                        } catch(AccessException me) {
                        throw new CloseOrderRuntime("CloseOrder app failed to persist SDO graph.
                        Access="+mediator+"\nGraph="+graph, me);
                        }
                        }
                        

9. 關(guān)閉連接

以下代碼示例包含關(guān)閉數(shù)據(jù)庫(kù)連接的輔助方法。此代碼完成了圖 14 所示序列的步驟 (H) 的工作。


清單 8. closeConnectionWorker 方法

                        
                        private static void closeConnectionWorker(ConnectionWrapper conn) {
                        try {
                        conn.getConnection().close();
                        } catch (SQLException sqle) {
                        throw new CloseOrderRuntime("CloseOrder app failed to close
                        ConnectionWrapper="+conn, sqle);
                        }
                        }
                        

10. 檢查應(yīng)用程序異常

CloseOrderApplication 使用了以下異常,這些異常都位于 developerworks.sdo.example.exception 包內(nèi):


清單 9. CloseOrderApplication 所使用的異常

                        
                        public class CloseOrderRuntime extends RuntimeException {
                        public CloseOrderRuntime() {
                        super();
                        }
                        public CloseOrderRuntime(String msg) {
                        super(msg);
                        }
                        public CloseOrderRuntime(Exception nested) {
                        super(nested);
                        }
                        public CloseOrderRuntime(String msg, Exception nested) {
                        super(msg, nested);
                        }
                        }
                        public class NoCustomer extends Exception {
                        public NoCustomer() {
                        super();
                        }
                        public NoCustomer(String msg) {
                        super(msg);
                        }
                        }
                        public class OrderNotOpen extends Exception {
                        public OrderNotOpen() {
                        super();
                        }
                        public OrderNotOpen(String msg) {
                        super(msg);
                        }
                        }
                        

11. 使用 Servlet 測(cè)試應(yīng)用程序

  1. 右鍵單擊 Deployment Descriptor: CloseOrderWeb 項(xiàng)目,然后選擇 New => Servlet...。

  2. 在 Name 字段輸入 TestCloseOrder,然后單擊 Next。

  3. 在 Java package 中輸入 developerworks.sdo.example.test,然后單擊 Finish

  4. 插入以下代碼作為 doGet 方法的內(nèi)容:


    清單 10. 測(cè)試 Servlet
    
                                
                                protected void doGet(HttpServletRequest request, HttpServletResponse response) throws
                                ServletException, IOException {
                                String customerId = request.getParameter("customerId");
                                CloseOrderApplication coa = new CloseOrderApplication();
                                coa.closeOrder(Integer.parseInt(customerId));
                                response.getWriter().print("Close order request processed successfully.");
                                }

  5. 選擇 Servers 選項(xiàng)卡,右鍵單擊 WebSphere Application Server v6.0,然后選擇 Start

  6. 再次右鍵單擊服務(wù)器,并選擇 Add and remove projects...,以將 CloseOrder EAR 項(xiàng)目部署到服務(wù)器。

  7. 部署了項(xiàng)目之后,使用以下 URL 在 Web 瀏覽器中打開(kāi)管理控制臺(tái):http://localhost:9060/admin。

  8. 選擇 Log in => Security => Global security => JAAS Configuration => J2C Authentication data => New,并按照?qǐng)D 15 所示填寫(xiě)表單。


    圖 15. 數(shù)據(jù)庫(kù)身份驗(yàn)證入口
    圖 15. 數(shù)據(jù)庫(kù)身份驗(yàn)證入口
  9. 選擇 OK,然后選擇 Save。

  10. 選擇 Environment => WebSphere Variables => DB2UNIVERSAL_JDBC_DRIVER_PATH 并輸入您的 DB2 驅(qū)動(dòng)程序目錄。Windows 下的缺省值為 C:\Program Files\IBM\SQLLIB\java。

  11. 選擇 Resources => JDBC Providers => New 并按照?qǐng)D 16 所示填寫(xiě)表單。


    圖 16. JDBC Provider 配置
    DB2-Provider.PNG
  12. 依次單擊 Next、OKSave。

  13. 選擇 DB2 Universal JDBC Driver Provider (XA) => Data sources => New。

  14. 插入 jdbc/db2/Example 作為 JNDI name。

  15. 選擇 DB2 Login 作為 Component-managed authentication alias。

  16. 輸入 EXAMPLE 作為 Database name。

  17. 輸入 localhost(或 DB2 的主機(jī))作為 Server name,然后單擊 Save。

  18. 為了確保數(shù)據(jù)源正常工作,請(qǐng)選擇 DB2 Universal JDBC Driver XA DataSource 旁邊的框,并單擊 Test connection

  19. 最后一個(gè)管理步驟就是 metadata.xml 文件的 JNDI 字符串綁定。選擇 Environment => Naming => Name Space Bindings => New => String => Next 并按照?qǐng)D 17 所示填寫(xiě)表單。Name Space value 中的 Name 為 string/CloseOrderApp/metadata。


    圖 17. XML 文件名字符串綁定
    圖 17. XML 文件名字符串綁定
  20. 選擇 Next => FinishSave。

  21. 重新啟動(dòng)服務(wù)器,以確保所有 JNDI 綁定均已更新。

  22. 若要運(yùn)行該應(yīng)用程序,請(qǐng)將以下 URL 輸入到 Web 瀏覽器中:http://localhost:9080/CloseOrderWeb/TestCloseOrder?customerId=2





回頁(yè)首


結(jié)束語(yǔ)

JDBC Data Access Service 提供了對(duì)面向服務(wù)的體系結(jié)構(gòu)的持久化層的標(biāo)準(zhǔn)化訪(fǎng)問(wèn)。本文演示了 SDO DAS 如何如何適應(yīng)大型的企業(yè)部署,以及如何使用簡(jiǎn)潔且用戶(hù)友好的 XML 元數(shù)據(jù)將現(xiàn)有數(shù)據(jù)庫(kù)架構(gòu)映射到 SDO。





回頁(yè)首



    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶(hù) 評(píng)論公約

    類(lèi)似文章 更多