1. 程式人生 > >資料和服務 – 通向企業服務匯流排(ESB)之路

資料和服務 – 通向企業服務匯流排(ESB)之路

在前面的章節中,我們已經學習了XML的基礎知識以及基於XMLWeb服務。現在,我們就可以從企業級的視角,看看這些是如何組裝起來。對企業使用者來說,資訊及資訊的基本構成元素資料是他們所感興趣的。資料可以駐留在任何資料儲存中心,並以各種形式存在。如果不考慮資料儲存和格式,您需要將資料存到表中,並應用企業業務邏輯對它們進行處理,然後它們才能變為資訊提供給使用者。那麼,在SOA世界,我們怎樣才能從傳統的JDBCORM(Object-relations mapping, 資料關係對映)中解脫出來?而且,更加另我們感興趣的是,資料甚至可以以服務的形式存在,如果是這樣,我們怎樣將多個服務組合起來,並對它們進行查詢,就象我們將多個

JDBC查詢結果組合起來那樣?在本章中,我們將看一下這些問題,本章主要內容有:

JDO作為替代JDBC的可選方案;

資料服務及其在SOA中的角色;

即將出現的資料服務標準,例如SCASDO

Apache Tuscany進行介紹;

介紹MOM(message-oriented middleware,訊息中介軟體)

企業服務匯流排ESB(Enterprise Service Bus)—一種全新的架構體系

介紹OpenESB

JDO簡介

您對JDBCORM框架(HibernateToplink)已駕輕就熟,但現在我們卻要介紹Java另外一種資料訪問形式 – JDO(Java Data Object

Java資料物件),它是一種標準實現,它使用標準的基於介面的持久化抽象模型,對資料來源進行訪問。最初的JDO規範(JDO1.0)相當有年頭了,它基於JSR12(Java Specification 12)規範,是在Sun公司的領導下制定的。JDO現在的版本為JDO2.0,它實現了JSR243規範。從JDO2.0開始,其API的開發和參考實現都交由Apache開源社群完成,JDO也演變為Apache的一個開源專案。

為什麼要使用JDO

我們都有使用JDBC從關係資料庫中提取資料的程式設計經驗。但現在的問題是,我們是否需要另一種標準 – JDO來訪問資料?作為一名軟體開發者,如果您認為您需要對您的業務問題提供解決方案,您會從業務用例開始

(business use cases),分析業務邏輯,最後得到業務域物件模型(BDOMBusiness Domain Object Model),這樣做是很明智的。因為業務域物件模型(BDOM)將會指導您對實體類進行設計,這些實體類將被持久化,因此,它們可以用來儲存資料;一旦您完成實體類及它們之間的關係的設計,接下來的問題是,您是否應該編寫程式碼建立表,並持久化資料或查詢表(在沒有資料表的情況下,可以是其它種類的資料來源)中的資料?我對這個的問題的答案是“否”。因為您寫的程式碼越多,您出錯的機率就越大;再者,開發人員的時間是寶貴的;而且,技術也在不斷更新,今天您也許使用JDBC實現上面所提的“技術性功能”,明天您也許想把關係資料庫中的資料遷移到另一種資料儲存中,這時,您就會修改您所有的JDBC程式碼,以適合新的標準。在這種情況下,JDO就可以派上用場了。下面我們先來小結一下JDO不同於其它類似框架的特色:

分離關注點:使用JDO,應用開發者可以專注於業務領域物件模型(BDOM),而將那些資料持久化的細節(如資料的儲存及提取)留給JDO

JDO是基於介面的:JDO是一種基於Java介面的程式設計模型,因此,所有的持久化行為,如ORM框架中的一些最常用的功能,是以元資料(metadata)的形式存在,元資料獨立於您的BDOM原始碼;另外,您也可以以即插即用(Plug and Play, PNP)的方式使用多種JDO實現。

資料儲存方式的可移動性:持久化儲存方式不管是關係型的,還是基於物件,或者只是一個XML資料庫或扁平檔案,JDO的實現都能支援它們。因此,基於JDO的應用是獨立於底層資料庫的。

效能:JDO知道如何更好地同資料儲存中心進行互動,同開發者編寫的程式碼相比,這可以提高資料訪問的效能。

J2EE的整合:JDO應用可以利用J2EE的一些特點,如EJB及遠端訊息處理、自動分散式交易的協作、安全等這些J2EE企業級特色。

JPOX—Java持久化物件

JPOXApache的一個開源專案,它使用JDO,為Java訪問異種資料來源提供了一種解決方案。我們這裡指的JPOX JDO支援的異種資料來源,主要包括下列持久化方案四個主要方面特色的各種組合:持久化定義:它定義瞭如何將您的BDOM類持久化到資料儲存中;

持久化API:用來持久化您的BDOM物件的API程式設計介面;

查詢語言:按照特定的條件來查詢物件的一種語言;

資料儲存:儲存您的物件的底層資料儲存中心。

使用JPOXJDO示例

在本例中,我們將使用我們熟悉的訂單(Order)和商品(LineItems),將它們擴充套件到JDO實現。假定您已下載並把JPOX庫解壓到您的本地硬碟。

本例中的BDOM(業務域物件模型)

為方便討論,我們這裡只考慮兩個實體類,即OrderList(訂單列表)LineItem(單個商品),這兩個類的屬性及它們的關係如下圖所示:

上面的BDOM表明,一個訂單可以包含多個商品,而一個商品屬於且僅屬於一個訂單。

JDO中的BDOM實體類原始碼

BDOM中的實體類非常簡單,只為每個屬性提供了gettersetter方法。接下來,這些類需要通過JDO的配置檔案連線到JDO,從而可以利用JDO的持久化的能力,但這些完全獨立於核心的實體類。

OrderList.java

OrderList類代表訂單(Order),它有一個主鍵屬性number

public class OrderList{

private int number;

private Date orderDate;

private Set lineItems;

// other getter & setter methods go here

// Inner class for composite PK

public static class Oid implements Serializable{

public int number;

public Oid(){

}

public Oid(int param){

this.number = param;

}

public String toString(){

return String.valueOf(number);

}

public int hashCode(){

return number;

}

public boolean equals(Object other){

if (other != null && (other instanceof Oid)){

Oid k = (Oid)other;

return k.number == this.number;

}

return false;

}

}

}

LineItem.java

LineItem代表訂單中包含的每個商品,雖然JDO中可以為LineItem定義主鍵,但這裡我們並沒有為它顯示地定義主鍵。

public class LineItem{

private String productId;

private int numberOfItems;

private OrderList orderList;

// other getter & setter methods go here

}

package.jdo

JDO需要一個XML配置檔案,來定義要持久化的資料列,以及這些列使用何種JDBCJDO進行封裝對映。為此,我們可以建立一個名為package.jdoXML檔案,其內容如下,並把它放到和JDO實體類相同的目錄中。

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE jdo SYSTEM "file:/javax/jdo/jdo.dtd">

<jdo>

<package name="com.binildas.jdo.jpox.order">

<class name="OrderList" identity-type="application"

objectid-class="OrderList$Oid" table="ORDERLIST">

<field name="number" primary-key="true">

<column name="ORDERLIST_ID"/>

</field>

<field name="orderDate">

<column name="ORDER_DATE"/>

</field>

<field name="lineItems" persistence-modifier="persistent"

mapped-by="orderList">

<collection element-type="LineItem">

</collection>

</field>

</class>

<class name="LineItem" table="LINEITEM">

<field name="productId">

<column name="PRODUCT_ID"/>

</field>

<field name="numberOfItems">

<column name="NUMBER_OF_ITEMS"/>

</field>

<field name="orderList" persistence-modifier="persistent">

<column name="LINEITEM_ORDERLIST_ID"/>

</field>

</class>

</package>

</jdo>

jpox.PROPERTIES

本例中,我們將把我們的實體類持久化到關係資料庫Oracle中,我們需要在jpox.PROPERTIES檔案中指定主要的資料庫連線引數:

javax.jdo.PersistenceManagerFactoryClass=org.jpox.jdo.JDOPersistenceManagerFactory

javax.jdo.option.ConnectionDriverName=oracle.jdbc.driver.OracleDriver

javax.jdo.option.ConnectionURL=jdbc:oracle:thin:@127.0.0.1:1521:orcl

javax.jdo.option.ConnectionUserName=scott

javax.jdo.option.ConnectionPassword=tiger

org.jpox.autoCreateSchema=true

org.jpox.validateTables=false

org.jpox.validateConstraints=false

Main.java

這個類用來測試JDO的功能,其程式碼如下,它首先建立兩個訂單(Order)物件,然後為每個訂單新增幾個商品,然後它持久化這些實體類物件,並通過id屬性來查詢返回這些實體化物件。

public class Main{

static public void main(String[] args){

Properties props = new Properties();

try{

props.load(new FileInputStream("jpox.properties"));

}

catch (Exception e){

e.printStackTrace();

}

PersistenceManagerFactory pmf =

JDOHelper.getPersistenceManagerFactory(props);

PersistenceManager pm = pmf.getPersistenceManager();

Transaction tx = pm.currentTransaction();

Object id = null;

try{

tx.begin();

LineItem lineItem1 = new LineItem("CD011", 1);

LineItem lineItem2 = new LineItem("CD022", 2);

OrderList orderList = new OrderList(1, new Date());

orderList.getLineItems().add(lineItem1);

orderList.getLineItems().add(lineItem2);

LineItem lineItem3 = new LineItem("CD033", 3);

LineItem lineItem4 = new LineItem("CD044", 4);

OrderList orderList2 = new OrderList(2, new Date());

orderList2.getLineItems().add(lineItem3);

orderList2.getLineItems().add(lineItem4);

pm.makePersistent(orderList);

id = pm.getObjectId(orderList);

System.out.println("Persisted id : "+ id);

pm.makePersistent(orderList2);

id = pm.getObjectId(orderList2);

System.out.println("Persisted id : "+ id);

orderList = (OrderList) pm.getObjectById(id);

System.out.println("Retreived orderList : " + orderList);

tx.commit();

}

catch (Exception e){

e.printStackTrace();

if (tx.isActive()){

tx.rollback();

}

}

finally{

pm.close();

}

}

}

編譯並執行JDO例項程式

首先,如果您沒有修改過本章下載程式碼中的examples.PROPERTIES檔案,請編輯該檔案,將其中的目錄路徑指向您的開發環境。在您下載的本章程式碼中,也包含一個README.txt檔案,它也說明了編譯和執行本例的詳細步驟。因為我們使用Oracle來持久化實體類,我們還需要把下面兩個庫檔案加到classpath中:

jpox-rdbms*.jar

classes12.jar

我們還需要其它一些庫檔案,您可以在build.xml檔案中找到它們,請下載這些jar檔案,並相應地修改examples.PROPERTIES配置檔案中的路徑。要編譯本例,首先啟動您的資料庫伺服器,然後鍵入ant命令編譯編譯它,您可以進到本書原始碼的ch04/jdo目錄,並執行下面的命令:

cd ch04/jdo

ant

上面的命令將執行下列步驟:

首先,它編譯Java原始碼;然後JPOX庫對每個持久化類的位元組碼進行增強;

然後,它將在資料庫中建立所需的資料庫模式(表的定義)

要執行本例,請執行下面的ant命令:
ant run

您現在可以交叉檢查您的實體類是否儲存(持久化)到資料庫,下圖顯示了Oracle資料庫中的訂單及其子元素商品資料。