Castor功能與應用參考-XML框架

索引
3.1.3 小結
3.4總結
1. 項目簡介
Castor是一個開源的Java項目。其主要目標是在XML數據、Java對象和數據庫關係數據之間提供一種直接的映射,使得這三種對象數據可以相互之間自由轉換。Castor項目在2000年3月發佈第一個0.8版本,項目幾經重構設計目前最新版本爲1.1.2.1。
Castor項目主要包括XML與 Java對象的映射(Castor XML),Java對象與關係數據庫表映射(Castor JDO)兩個關鍵功能。在Castor中,我們通過定義數據映射(Mapping)文件,在XML文檔元素(節點、屬性、文本等),Java類(類、字段 屬性等)和數據庫表(關聯表、表、字段)之間建立一一映射。通過XML Schema定義可以自動生成實體Java類定義,通過實體Java類定義可以自動生成XML元素與Java類之間的映射文件。
目前,優秀的Java對象關係映射 (O/R Mapping)框架已經很多,商業化的如Oracle的TopLink,開源的如Hibernate,iBatis,Cayenne等,這些O/R框架 的實現各有特點。Sun針對對象關係映射提出了JDO規範,針對XML與Java對象之間的綁定提出了JAXB規範。Castor的優勢在於其提供O/R 映射功能的同時提供了XML與Java對象間數據映射功能,通過使用集成的映射定義文件, XML數據,Java對象和關係數據之間可以無縫的相互轉換。
2. Castor功能特性
1.Castor XML在Java對象模型與XML InfoSet之間建立相互轉換和數據綁定功能;
2.提供從XML文檔定義自動是生成Java類定義文件的功能(Code Generator);
3.通過自省方式在XML文檔與Java對象間建立映射(不需要提供XML Schema和XML Mapping文件);
4.通過定義映射文件在XML文檔實體與Java對象實體間建立映射;
5.Castor JDO 爲Java對象與數據庫關係數據之間提供一種序列化與反序列化的框架。Castor JDO不同於Sun公司提出的JDO概念,但兩者具有相似的目標;
6.Castor JDO以映射文件的方式定義Java對象模型與關係數據庫表模型之間的映射;
7.基於XML映射文件的方式定義三種不同數據對象模型之間的映射;
8.提供內存緩存和提交寫入(write at commit)方式,減少數據庫JDBC操作;
9.支持兩階段事務,對象操作回滾和數據庫鎖定偵測;
10.支持OQL與標準SQL之間的映射,Castor JDO對象查詢採用OQL語言;
11.提供基於Java實體對象類定義生成映射文件的功能;
12.提供基於XML輸入文檔生成Schema定義文件的功能;
我們將在下述章節中詳細介紹Castor的上述功能,並給出操作示例。
3. Castor XML
Castor XML作爲一個數據綁定框架,可以實現任何類似Java Bean的對象和XML文檔表示之間的相互轉換。通常情況下,Castor使用一組類描述符(ClassDescriptor)和字段描述符 (FieldDescriptor)集來定義一個Java對象如何編組(Marshall)成XML數據或者從XML數據解編(Unmarshall)爲 Java對象。
3.1XML編組(Marshalling)框架
XML編組框架實現Java對象與 XML文檔間的相互轉換。在下文中,除非顯式提及,否則編組框架指編組和解編兩種功能。Castor XML編組框架包含在兩個主要的類org.exolab.castor.xml.Marshaller和 org.exolab.castor.xml.Unmarshaller中。Castor XML編組解編功能示意如下圖所示:
Castor XML Databinding
3.1.1 自省方式(introspection)的編組與解編
下面我們通過一個簡單的示例展示XML編組框架以自省的方式在Java對象與XML文檔之間轉換的功能。首先,定義一個簡單的Person類,該類包含兩個字段:name和 birthday,分別指定義某個人的名字和出生日期。Person類定義如下:
import java.util.Date;
/**Ansimplepersonclass*/
publicclass Person implements java.io.Serializable {
/**Thenameoftheperson*/
private String name = null;
/**TheDateofbirth*/
private Date birthday = null;

/**CreatesaPersonwithnoname*/
public Person() {
super();
}
/**CreatesaPersonwiththegivenname*/
public Person(String name) {
this.name = name;
}
/**
*@returndateofbirthoftheperson
*/
public Date getDateOfBirth() {
returnbirthday;
}
/**
*@returnnameoftheperson
*/
public String getName() {
returnname;
}
/**
*Setsthedateofbirthoftheperson
*@paramnamethenameoftheperson
*/
publicvoid setDateOfBirth(Date birthday) {
this. birthday = birthday;
}
/**
*Setsthenameoftheperson
*@paramnamethenameoftheperson
*/
publicvoid setName(String name) {
this.name = name;
}
}
然後,我們定義一個Person類的實例並將其編組輸出爲XML,示例代碼如下:
// 創建一個新的Person對象
Person person = new Person("Ryan 'Mad Dog' Madden");
Calendar birthday = new GregorianCalendar(1955, 8, 15);
person.setDateOfBirth(birthday.getTime());

// 構建編組後的XML文檔輸出
FileWriter writer = new FileWriter("d://test.xml");

// 編組Person實例爲XML文檔
Marshaller.marshal(person, writer);
上述代碼輸出結果爲:
<?xml version="1.0" encoding="UTF-8"?>
<person>
<name>Ryan 'Mad Dog' Madden</name>
<date-of-birth>3855-09-15T00:00:00.000+08:00</date-of-birth>
</person>
下面的代碼讀取上述輸出的XML文檔並將解編爲Java對象:
// 構建輸入XML文檔的Reader
FileReader reader = new FileReader("d://test.xml");

// 解編XML文檔爲Person對象
person = (Person) Unmarshaller.unmarshal(Person.class, reader);

System.out.println("Name="+person.getName());
輸出結果爲:
Name=Ryan 'Mad Dog' Madden

 

3.1.2 使用映射文件方式的編組與解編
調用Marshaller和 Unmarshaller的實例方法時,必須提供XML文檔結構和Java類模型間的映射定義文件。關於Mapping映射文件的定義我們會在下述章節中 給出詳細介紹。下面是調用Marshaller和Unmarshaller的實例方法的代碼示例:
// 加載映射文件
Mapping mapping = new Mapping();
mapping.loadMapping("mapping.xml");

// 爲待解編的XML文檔構建一個Reader
reader = new FileReader("test.xml");

// 構建一個解編器 Unmarshaller
Unmarshaller unmarshaller = new Unmarshaller(Person.class);
unmarshaller.setMapping(mapping);
// 解編XML文檔爲Person對象
Person person = (Person) unmarshaller.unmarshal(reader);

 

3.1.3 小結
上述示例展示了使用 Marshaller和Unmarshaller類的靜態方法以自省的方式實現XML文檔與Java對象之間的編組和解編,以及使用Mapping映射文 件通過調用Marshaller和Unmarshaller的實例方法實現XML文檔與Java對象之間的編組和解編兩種方式。
前一種方式不需要構造 Marshaller和Unmarshaller的實例;後一種方式需要構造Marshaller和Unmarshaller的實例,調用非靜態方法完成 上述功能。調用Marshaller和Unmarshaller的實例方法時,必須提供XML文檔結構和Java類模型間的映射定義文件。
注意:當使用MarshallerUnmarshaller的靜態方法時,即使指定了映射定義文件,此映射定義也會被忽略。
3.2Castor XML的編組/解編機制
Castor通過類描述符和字段描述符 幾乎可以編組/解編所有的Java對象。當某個Java對象類描述符不存在時,編組框架通過使用反射(Reflection)方式獲取對象的結構信息,並 在內存中爲此對象構造類描述符和字段描述符。當實體類的描述符存在時,Castor使用這些描述符提供的Java對象模型信息用來處理編組和解編。
編組與解編過程中,Castor要求實體類定義必須提供"public"類型的默認構造函數(不含參數)聲明以及必要的"getter"和"setter"方法。
3.2.1 類描述符
類描述符(org.exolab.castor.xml.XMLClassDescriptor)使得編組框架具有足夠的信息以正確的處理編組/解編過程。在Castor中,類描述符由XML編組框架和JDO框架(後文詳細描述)共享。每個類描述符包含一組字段描述符(org.exolab.castor.xml.XMLFieldDescriptor)。
XML 類描述符具有兩種構建方式:編譯時構建和運行時構建。
l 編譯時構建描述符
在編譯時構建類描述符,一種方法是爲每一個需要編組的實體類實現org.exolab.castor.xml.XMLClassDescriptor接口;另一種方式是使用Castor提供的源代碼生成器通過XML Schema定義文檔在生成Java實體類定義的同時,爲Java實體類生成相應的類描述符。
編譯時構建類描述符的方式的主要優點是其執行速度快於運行時構建方式。
l 運行時構建描述符
使用運行時構建類描述符時, Castor可以直接通過反射自省方式Java實體類,也可以提供映射定義文件。這兩種方式可以結合使用。對於默認的自省方式,實體類必須爲必要的字段提 供適當的setter/getter方法;如果沒有給編組的字段數據指定setter/getter方法,Castor只能訪問類型爲"public"的 字段。如果上述條件都不滿足,Castor將不處理上述字段。
在Castor中,自省方式默認啓動, 不需要做任何設置。用戶可以在castor.properties文件中設定必要的參數來控制自省方式的行爲,如字段命名慣例,原始類型默認看作XML屬 性還是節點(Element)。用戶可以查看castor.properties文件(在Castor發佈Jar包中的 "org/exolab/castor"路徑下)獲取詳細信息。
使用映射文件描述實體類時,用戶需要在編組/解編操作前加載映射定義。映射定義參考(org.exolab.castor.mapping.Mapping)。
3.3使用XMLContext獲取編組器和解編器
Castor自 V1.1.2版本開始在XML編組框架中提供了XMLContext類,用於方便高效的獲取Marshaller和Unmarshaller實例。上述3.1節中編組解編Person類實例的例子使用XMLContext實現的方式如下:
import org.exolab.castor.xml.XMLContext;
import org.exolab.castor.mapping.Mapping;
import org.exolab.castor.xml.Unmarshaller;
// 構建Mapping實例
Mapping mapping = XMLContext.createMapping();
mapping.loadMapping("mapping.xml");

// 構建一個XMLContext實例並設定映射
XMLContext context = new XMLContext();
context.addMapping(mapping);

// 構建一個Unmarshaller
Unmarshaller unmarshaller = context.createUnmarshaller();
unmarshaller.setClass(Person.class);

// 爲待解編的XML文檔構建一個Reader
Reader reader = new FileReader("test.xml");

// XML文檔中解編person對象
Person person = (Person) unmarshaller.unmarshal(reader);
如上述代碼所示,XMLContext提供了不同的工廠方法用於獲取新的 Marshaller,Unmarshaller和Mapping實例。當在一個應用中需要使用不止一個Unmarshaller實例時,可以根據需要調 用XMLContext的createUnmarshaller實例方法。從同一個XMLContext實例獲取多個Unmarshaller實例時開銷 很小。需要注意的是,Unmarshaller不是線程安全的。
 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章