??xml version="1.0" encoding="utf-8" standalone="yes"?>激情综合亚洲色婷婷五月,久久亚洲av无码精品浪潮,亚洲最大的视频网站http://www.tkk7.com/lcwlv929/category/26052.htmlzh-cnSun, 23 Sep 2007 15:44:38 GMTSun, 23 Sep 2007 15:44:38 GMT60Portal Framework介绍http://www.tkk7.com/lcwlv929/articles/147079.html?/dc:creator>?/author>Fri, 21 Sep 2007 05:23:00 GMThttp://www.tkk7.com/lcwlv929/articles/147079.htmlhttp://www.tkk7.com/lcwlv929/comments/147079.htmlhttp://www.tkk7.com/lcwlv929/articles/147079.html#Feedback0http://www.tkk7.com/lcwlv929/comments/commentRss/147079.htmlhttp://www.tkk7.com/lcwlv929/services/trackbacks/147079.html阅读全文

]]>
XML ?Java 技? ?Castor q行数据l定http://www.tkk7.com/lcwlv929/articles/145063.html?/dc:creator>?/author>Fri, 14 Sep 2007 02:29:00 GMThttp://www.tkk7.com/lcwlv929/articles/145063.htmlhttp://www.tkk7.com/lcwlv929/comments/145063.htmlhttp://www.tkk7.com/lcwlv929/articles/145063.html#Feedback0http://www.tkk7.com/lcwlv929/comments/commentRss/145063.htmlhttp://www.tkk7.com/lcwlv929/services/trackbacks/145063.html对于主要兛_文档数据内容的应用程序,Java XML 数据l定是一U代?XML 文档模型的强大机制。本文中Q企?Java 专家 Dennis Sosnoski 介绍数据l定Qƈ讨论什么它如此o人瞩目。然后,他向读者展CZ如何利用 Java 数据l定的开放源代码 Castor 框架来处理日益复杂的文档。如果您的应用程序更多的?XML 作ؓ数据而不是文档,您就会愿意了解这U处?XML ?Java 技术的单有效的Ҏ?/blockquote>

应用E序中?XML 文档的多数方法都把重Ҏ?XML 上:?XML 的观点用文档,按照 XML 元素、属性和字符数据内容~程。如果应用程序主要关心文档的 XML l构Q那么这U方法非常好。对于更兛_文档中所含数据而非文档本n的许多应用程序而言Q?数据l定提供了一U更单的使用 XML 的方法?

文档模型与数据绑?/span>

本系列文章的上一(请参?参考资?/a>Q所讨论的文档模型,是与数据l定最接近的替代方案。文档模型和数据l定都在内存中徏立文档的表示Q都需要在内部表示和标准文?XML 之间双向转换。两者的区别在于文档模型可能保?XML l构Q而数据绑定只兛_应用E序所使用的文档数据?

Z说明q一点,?1 l出了一个简?XML 文档的数据模型视图。文档成分——在q个例子中只有元素和文本节点——通过反映原始 XML 文档的结构连接在一赗Ş成的节点树很Ҏ和原始文档联p,但要解释树中表示的实际数据就不那么容易了?/p>
?1. 文档的文档模型视?/strong>
文档的文档模型视? src=

如果应用E序使用 XML 文档模型ҎQ您需要处理这U类型的树。这U情况下Q您用节点之间的父子关系在树的上下层之间DQ用属于同一父节点的子女之间的兄弟关pd树的同一层中D。您可以非常详尽地处理树l构Q当把树序列化ؓ文本Ӟ生成?XML 文档反映您所做的修改Q比如插入的注释Q?/p>

现在来看看与?1 截然不同的图 2Q它表示同一文档的数据绑定视图。在q里Q{换过E几乎隐藏了原始 XML 文档的所有结构,但是因ؓ只有通过两个对象Q更Ҏ看清楚真正的数据Q也更很Ҏ讉Kq些数据?/p>
?2. 文档的数据绑定视?/strong>
文档的数据绑定视? src=

使用q种数据l构像是一般的 Java ~程——甚x本不需要知?XMLQ(哦,q是不要走得 ?/em>q了——我们这些专安问还得活……Q您的项目中臛_要有人明白,q种数据l构?XML 文档之间的映是如何建立的,但这仍然是向化迈出的一大步?

?仅仅是编E的化,数据l定q带来其他的好处。与文档模型Ҏ相比Q因为抽掉了许多文档l节Q数据绑定通常需要的内存更少。比如前面两个图中所C的数据l构Q文档模型方法用了 10 个单独的对象Q与此相比数据绑定只使用了两个。要创徏的东西少Q构造文档的数据l定表示可能更快一些。最后,数据l定与文档模型相比,应用E序可以更快地访问数据,因ؓ您可以控制如何表C和存储数据。我后面q要讲到q一炏V?

既然数据l定那么好,Zq要使用文档模型呢?以下两种情况需要用文档模型:

  • 应用E序真正x文档l构的细节。比方说Q如果您在编写一?XML 文档~辑器,您就会坚持用文档模型而非数据l定?
  • 您处理的文档没有固定的结构。比如实CU通用?XML 文档数据库,数据l定׃是一U好办法?

许多应用E序使用 XML 传输数据Q但q不兛_文档表示的细节。这cd用程序非帔R合使用数据l定。如果您的应用程序符合这U模式,Ll读下去?/p>



回页?/strong>


Castor 框架

目前有几U不同的框架支持 Java XML 数据l定Q但q没有标准的接口。这U情冉|l会得到改变QJava Community Process (JCP) ?JSR-031 正在努力定义q方面的标准Q请参阅 参考资?/a>Q。现在让我们选择一个框架ƈ学习使用它的接口?

本文选择?Castor 数据l定框架。Castor 目采用 BSD cd的证书,因此可在Mcd的应用程序(包括完整版权的项目)中用?Castor 实际上仅仅有 XML 数据l定Q它q支?SQL ?LDAP l定Q尽本文中不讨些其他的Ҏ。该目?2000 q初开始发P目前处于?beta 状态(一般可以用这个版本,但是如果需要问题修正,您可能需要升U到目前?CVS 版本Q。请参阅 参考资?/a>部分?Castor 站点链接Q以了解更多的细节ƈ下蝲该Y件?





回页?/strong>


默认l定

Castor XML 数据l定很容易上手,甚至不需要定?XML 文档格式。只要您的数据用c?JavaBean 的对象表C,Castor p自动生成表示q些数据的文档格式,然后从文档重构原始数据?/p>
数据l定词汇?/strong>

下面q个小的词汇表列出了本文中要用到的一些术语:

~组是在内存中生成对象的 XML 表示的过E。与 Java 序列化一Pq种表示需要包括所有依赖的对象Q主对象引用的对象、这些对象引用的其他对象、等{?

解组是上q过E的逆过E,在内存中?XML 表示创徏对象Q以及依赖的对象Q?

映射是用于编l和解组的一些规则。Castor 有一些内建的规则定义了默认映,本文q一部分要描述。它也允许您使用单独的映文Ӟ参见后述?

那么“c?JavaBean”是什么意思呢Q真正的 JavaBean 是可视化lgQ可以在开发环境中配置以用?GUI 布局。一些源于真?JavaBean 的惯例已l被 Java 团体普遍接受Q特别是对于数据cR如果一个类W合以下惯例Q我q之ؓ?#8220;c?JavaBean”的:

  • q个cL公共?
  • 定义了公q默认Q没有参敎ͼ构造函?
  • 定义了公q getX ?setX Ҏ讉K属性(数据Q?

关于技术定义已l扯得太q了Q当提到q些c?JavaBean cLQ我不再重复说明,只是UC?#8220;bean”cR?/p>

在整文章中Q我用航U班机时刻表作ؓCZ代码。我们从一个简单的 bean cd始说明它的工作原理,q个c表CZ个特定的航班Q包括四个信息项Q?/p>

  • 飞机~号Q航I公司)
  • 航班~号
  • 起飞旉
  • 抵达旉

下面的清?1 l出了处理航班信息的代码?/p>
清单 1. 航班信息 bean
public class FlightBean
            {
            private String m_carrier;
            private int m_number;
            private String m_departure;
            private String m_arrival;
            public FlightBean() {}
            public void setCarrier(String carrier) {
            m_carrier = carrier;
            }
            public String getCarrier() {
            return m_carrier;
            }
            public void setNumber(int number) {
            m_number = number;
            }
            public int getNumber() {
            return m_number;
            }
            public void setDepartureTime(String time) {
            m_departure = time;
            }
            public String getDepartureTime() {
            return m_departure;
            }
            public void setArrivalTime(String time) {
            m_arrival = time;
            }
            public String getArrivalTime() {
            return m_arrival;
            }
            }

您可以看刎ͼq个 bean 本n没有什么意思,因此我想增加一个类q在默认?XML l定中用它Q如清单 2 所C?/p>
清单 2. 试默认的数据绑?/strong>
import java.io.*;
            import org.exolab.castor.xml.*;
            public class Test
            {
            public static void main(String[] argv) {
            // build a test bean
            FlightBean bean = new FlightBean();
            bean.setCarrier("AR");
            bean.setNumber(426);
            bean.setDepartureTime("6:23a");
            bean.setArrivalTime("8:42a");
            try {
            // write it out as XML
            File file = new File("test.xml");
            Writer writer = new FileWriter(file);
            Marshaller.marshal(bean, writer);
            // now restore the value and list what we get
            Reader reader = new FileReader(file);
            FlightBean read = (FlightBean)
            Unmarshaller.unmarshal(FlightBean.class, reader);
            System.out.println("Flight " + read.getCarrier() +
            read.getNumber() + " departing at " +
            read.getDepartureTime() +
            " and arriving at " + read.getArrivalTime());
            } catch (IOException ex) {
            ex.printStackTrace(System.err);
            } catch (MarshalException ex) {
            ex.printStackTrace(System.err);
            } catch (ValidationException ex) {
            ex.printStackTrace(System.err);
            }
            }
            }

Castor 不仅能用?bean

实际上,Castor 不仅仅能用于本文所q的c?JavaBean cR它也可以访问带有公共成员变量的单数据对象类的数据。比如,E微改动前述?Test c,您就可以对航班数据用如下的定义Qƈ最l得到同L XML 格式Q?

public class FlightData
                                    {
                                    public String carrier;
                                    public int number;
                                    public String departure;
                                    public String arrival;
                                    }

Z?Castor 正常工作Q一个类必须全部采用q种方式或那U方式。如果类定义?M getX ?setX ҎQCastor 将其视?beanQƈ在编l和解组时只使用q些Ҏ?

q段代码首先构造了一?FlightBean beanQƈ使用一些固定的数据初始化它。然后用?bean 默认?Castor XML 映射其写入一个输出文件。最后又d生成?XMLQ?同样使用默认映射重构 beanQ然后打印重构的 bean 中的信息。结果如下:

Flight AR426 departing at 6:23a and arriving at 8:42a

q个输出l果表明您已l成功地来回转换了航班信息(不算太糟Q只有两ơ方法调用)。现在我q不满于简单控制台输出Q准备再往深处挖一挖?/p>

q后

Z更清楚地了解q个例子中发生了什么,看一?Marshaller.marshal() 调用生成?XML。文档如下:

<?xml version="1.0"?>
            <flight-bean number="426">
            <arrival-time>8:42a</arrival-time>
            <departure-time>6:23a</departure-time>
            <carrier>AR</carrier>
            </flight-bean>

Castor 使用 Java 内部查机制检?Marshaller.marshal() 调用传递的对象。在本例中,它发C定义的四个属性倹{Castor 在输出的 XML 中创Z个元素(文档的根元素Q表C整个对象。元素名从对象的cd中衍生出来,在这里是 flight-bean 。然后Castor 用以下两U方法中的一个,把该对象的属性值包括进来:

  • 对于h基本cd值的属性创建元素的一个属性(本例中只?number 属性通过 getNumber() Ҏ公开?int |?
  • 对于每个h对象cd值的属性创建根元素的一个子元素Q本例中的所有其他属性,因ؓ它们是字W串Q?

 

l果是上面所C的 XML 文档?/p>



回页?/strong>


改变 XML 格式

如果不喜?Castor 的默认映格式,您可以方便地改变映射。在我们的航班信息例子中Q比方说Q假定我们需要更紧凑的数据表C。用属性代替子元素有助于实现这个目标,我们也许q希望用比默认的名字更短一些的名字。如下所C的文档可以很好地满我们的需要:

<?xml version="1.0"?>
            <flight carrier="AR" depart="6:23a" arrive="8:42a" number="426"/>

定义映射

Z?Castor 使用q种格式而非默认的格式,首先需要定义描q这U格式的映射。映描q本w(非常意外的)是一?XML 文档。清?3 l出了把 bean ~组成上q格式的映射?/p>
清单 3. 紧凑格式的映?/strong>
<!DOCTYPE databases PUBLIC
            "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
            "http://castor.exolab.org/mapping.dtd">
            <mapping>
            <description>Basic mapping example</description>
            <class name="FlightBean" auto-complete="true">
            <map-to xml="flight"/>
            <field name="carrier">
            <bind-xml name="carrier" node="attribute"/>
            </field>
            <field name="departureTime">
            <bind-xml name="depart" node="attribute"/>
            </field>
            <field name="arrivalTime">
            <bind-xml name="arrive" node="attribute"/>
            </field>
            </class>
            </mapping>

class 元素定义了一个命名类 FlightBean 的映。通过在该元素中加?auto-complete 属性ƈ把D?true Q您可以告诉 Castor 对于该类的Q何属性,只要没有在这个元素中专门列出Q就使用默认映射。这样非常简便,因ؓ number 属性已l按照希望的方式处理了?

子元?map-to 告诉 CastorQ要?FlightBean cȝ实例映射?XML 文档中的 flight 元素。如果您l箋使用默认的元素名 flight-bean Q参?q后节中默认映输出的例子Q,可以不用该元素?

最后,对于每个希望以非默认方式处理的属性,可以引入一?field 子元素。这些子元素都按照相同的模式Q?name 属性给出映的属性名Q?bind-xml 子元素告?Castor 如何映射那个属性。这里要求把每个属性映成l定名称的属性?

使用映射

现在已经定义了一个映,您需要告?Castor 框架在编l和解组数据时用那个映。清?4 说明了要实现q一点,需要对前面的代码做哪些修改?/p>
清单 4. 使用映射~组和解l?/strong>
...
            // write it out as XML (if not already present)
            Mapping map = new Mapping();
            map.loadMapping("mapping.xml");
            File file = new File("test.xml");
            Writer writer = new FileWriter(file);
            Marshaller marshaller = new Marshaller(writer);
            marshaller.setMapping(map);
            marshaller.marshal(bean);
            // now restore the value and list what we get
            Reader reader = new FileReader(file);
            Unmarshaller unmarshaller = new Unmarshaller(map);
            FlightBean read = (FlightBean)unmarshaller.unmarshal(reader);
            ...
            } catch (MappingException ex) {
            ex.printStackTrace(System.err);
            ...
            

与前?清单 2默认映射所用的代码相比Q这D代码稍微复杂一炏V在执行M其他操作之前Q首先要创徏一?Mapping 对象载入您的映射定义。真正的~组和解l也有区别。ؓ了用这个映,您需要创?Marshaller ?Unmarshaller 对象Q用定义的映配|它们,调用q些对象的方法,而不是像W一个例子那样用静态方法。最后,您必L供对映射错误产生的另一个异常类型的处理?

完成q些修改后,您可以尝试再ơ运行程序。控制台输出与第一个例子相同(?清单 2所C)Q但是现在的 XML 文档看v来符合我们的需要:

<?xml version="1.0"?>
            <flight carrier="AR" depart="6:23a" arrive="8:42a" number="426"/>





回页?/strong>


处理集合

现在单个航班数据已经有了我们喜欢的Ş式,您可以定义一个更高的结构:航线数据。这个结构包括v降机场的标识W以及在该航U上飞行的一l航班。清?5 l出了一个包含这些信息的 bean cȝ例子?/p>
清单 5. 航线信息 bean
import java.util.ArrayList;
            public class RouteBean
            {
            private String m_from;
            private String m_to;
            private ArrayList m_flights;
            public RouteBean() {
            m_flights = new ArrayList();
            }
            public void setFrom(String from) {
            m_from = from;
            }
            public String getFrom() {
            return m_from;
            }
            public void setTo(String to) {
            m_to = to;
            }
            public String getTo() {
            return m_to;
            }
            public ArrayList getFlights() {
            return m_flights;
            }
            public void addFlight(FlightBean flight) {
            m_flights.add(flight);
            }
            }

在这D代码中Q我定义了一?addFlight() ҎQ用于每ơ增加一个属于这条航U的航班。这是在试E序中徏立这U数据结构非常简便的办法Q但是可能和您预料的相反Q?Castor 在解l时q不使用U方法向航线中增加航班。相反,它?getFlights() Ҏ讉K一l航班,然后直接d到集合中?

在映中处理航班集合只需要稍微改变上一个例子(?清单 3所C)中的 field 元素。清?6 昄了修改后的映文件?


清单 6. 映射包含一l航班的航线
<!DOCTYPE databases PUBLIC
            "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
            "http://castor.exolab.org/mapping.dtd">
            <mapping>
            <description>Collection mapping example</description>
            <class name="RouteBean">
            <map-to xml="route"/>
            <field name="from">
            <bind-xml name="from" node="attribute"/>
            </field>
            <field name="to">
            <bind-xml name="to" node="attribute"/>
            </field>
            <field name="flights" collection="collection" type="FlightBean">
            <bind-xml name="flight"/>
            </field>
            </class>
            <class name="FlightBean" auto-complete="true">
            <field name="carrier">
            <bind-xml name="carrier" node="attribute"/>
            </field>
            <field name="departureTime">
            <bind-xml name="depart" node="attribute"/>
            </field>
            <field name="arrivalTime">
            <bind-xml name="arrive" node="attribute"/>
            </field>
            </class>
            </mapping>

一切都和上一个映(?清单 3所C)完全相同Q只不过?field 元素定义了一?RouteBean ?flights 属性。这个映用C两个原来不需要的属性?collection 属性的?collection 把该属性定义成一?java.util.Collection Q其他值分别定义数l,java.util.Vectors {等Q?type 属性定义包含在集合中的对象cdQ值是完整的限定类名。这里的值是 FlightBean Q因为对q些cL没有使用包?

另一个区别在 FlightBean cd素中Q不再需要?map-to 子元素定义绑定的元素名。定?RouteBean ?flights 属性的 field 元素Q通过它的 bind-xml 子元素定义了q一炏V因为编l或解组 FlightBean 对象只能通过该属性,它们永q用这?bind-xml 元素讑֮的名U?

我不再详l列个例子的试E序Q因为数据绑定部分和上一个例子相同。以下是用一些示例数据生成的 XML 文档Q?/p>
<?xml version="1.0"?>
            <route from="SEA" to="LAX">
            <flight carrier="AR" depart="6:23a" arrive="8:42a"
            number="426"/>
            <flight carrier="CA" depart="8:10a" arrive="10:52a"
            number="833"/>
            <flight carrier="AR" depart="9:00a" arrive="11:36a"
            number="433"/>
            </route>





回页?/strong>


对象引用

现在可以为处理完整的航班时刻表做最后的准备了。您q需要增加三?beanQ?

  • AirportBean 用于用于机场信息
  • CarrierBean 用于航线信息
  • TimeTableBean 把一切组合v?

Z保持味性,除了上一个例子(参阅 处理集合Q中用到?RouteBean ?FlightBean 之间的从属关p,您还要在 bean 之间增加一些联pR?

q接 bean

要增加的W一个联pL修改 FlightBean Q让它直接引用班Z息,而不再仅仅用代码标识班机。以下是?FlightBean 的修改:

public class FlightBean
            {
            private CarrierBean m_carrier;
            ...
            public void setCarrier(CarrierBean carrier) {
            m_carrier = carrier;
            }
            public CarrierBean getCarrier() {
            return m_carrier;
            }
            ...
            }

然后?RouteBean 做同L修改Q让它引用机Z息:

public class RouteBean
            {
            private AirportBean m_from;
            private AirportBean m_to;
            ...
            public void setFrom(AirportBean from) {
            m_from = from;
            }
            public AirportBean getFrom() {
            return m_from;
            }
            public void setTo(AirportBean to) {
            m_to = to;
            }
            public AirportBean getTo() {
            return m_to;
            }
            ...
            }

我没有给出新?bean 自n的代码,因ؓ和前面的代码相比没有什么新鲜的东西。您可以从下载文?code.jar 中找到完整的CZ代码Q请参阅 参考资?/a>Q?

映射引用

您可能需要映文档的其他一些特性,以支持编l和解组的对象之间的引用。清?7 l出了一个完整的映射Q?/p>
清单 7. 完整的时刻表映射
<!DOCTYPE databases PUBLIC
            "-//EXOLAB/Castor Mapping DTD Version 1.0//EN"
            "http://castor.exolab.org/mapping.dtd">
            <mapping>
            <description>Reference mapping example</description>
            <class name="TimeTableBean">
            <map-to xml="timetable"/>
            <field name="carriers" type="CarrierBean" collection="collection">
            <bind-xml name="carrier"/>
            </field>
            <field name="airports" type="AirportBean" collection="collection">
            <bind-xml name="airport"/>
            </field>
            <field name="routes" type="RouteBean" collection="collection">
            <bind-xml name="route"/>
            </field>
            </class>
            <class name="CarrierBean" identity="ident" auto-complete="true">
            <field name="ident">
            <bind-xml name="ident" node="attribute"/>
            </field>
            </class>
            <class name="AirportBean" identity="ident" auto-complete="true">
            <field name="ident">
            <bind-xml name="ident" node="attribute"/>
            </field>
            </class>
            <class name="RouteBean">
            <field name="from" type="AirportBean">
            <bind-xml name="from" node="attribute" reference="true"/>
            </field>
            <field name="to" type="AirportBean">
            <bind-xml name="to" node="attribute" reference="true"/>
            </field>
            <field name="flights" type="FlightBean" collection="collection">
            <bind-xml name="flight"/>
            </field>
            </class>
            <class name="FlightBean" auto-complete="true">
            <field name="carrier">
            <bind-xml name="carrier" node="attribute" reference="true"/>
            </field>
            <field name="departureTime">
            <bind-xml name="depart" node="attribute"/>
            </field>
            <field name="arrivalTime">
            <bind-xml name="arrive" node="attribute"/>
            </field>
            </class>
            </mapping>

除了新增?bean 之外Q这里有一个重要的变化Q就是增加了 identity ?reference 属性?class 元素?identity 属性,通知 Castor q个命名属性是该类实例的唯一标识W。在q里Q我?CarrierBean ?AirportBean ?ident 属性定义成它们的标识符?

bind-xml 元素?reference 属性,提供了对于该映射 Castor 所需要的另一部分链接信息?reference 设ؓ true 的映告?Castor ~组和解l引用对象的标识W,而不是对象本w的副本。从 RouteBean 链接 AirportBean Q表CU的h点)的引用,?FlightBean 链接 CarrierBean 的引用,都用了q种Ҏ?

?Castor 使用q种cd的映解l数据时Q它自动把对象标识符转化为对实际对象的引用。您需要保证标识符的值确实是唯一的,甚至不同cd的对象之间也要保证这U唯一性。对于本例中的数据,q一点不成问题:飞机的标识符是两个字W,而机场的标识W是三个字符Q永q不会冲H。如?有潜在冲H的可能性,只要在所代表的对象类型的每个标识W加上唯一的前~Q就可以很容易地避免q种问题?

~组后的时刻?/span>

q个例子的测试代码没有新东西Q只是增加了一些示例数据。清?8 l出了编lŞ成的 XML 文档Q?/p>
清单 8. ~组的时刻表
<?xml version="1.0"?>
            <timetable>
            <carrier ident="AR" rating="9">
            <URL>http://www.arcticairlines.com</URL>
            <name>Arctic Airlines</name>
            </carrier>
            <carrier ident="CA" rating="7">
            <URL>http://www.combinedlines.com</URL>
            <name>Combined Airlines</name>
            </carrier>
            <airport ident="SEA">
            <location>Seattle, WA</location>
            <name>Seattle-Tacoma International Airport</name>
            </airport>
            <airport ident="LAX">
            <location>Los Angeles, CA</location>
            <name>Los Angeles International Airport</name>
            </airport>
            <route from="SEA" to="LAX">
            <flight carrier="AR" depart="6:23a" arrive="8:42a" number="426"/>
            <flight carrier="CA" depart="8:10a" arrive="10:52a" number="833"/>
            <flight carrier="AR" depart="9:00a" arrive="11:36a" number="433"/>
            </route>
            <route from="LAX" to="SEA">
            <flight carrier="CA" depart="7:45a" arrive="10:20a" number="311"/>
            <flight carrier="AR" depart="9:27a" arrive="12:04p" number="593"/>
            <flight carrier="AR" depart="12:30p" arrive="3:07p" number="102"/>
            </route>
            </timetable>





回页?/strong>


使用数据

现在Q时刻表中的所有数据都最l完成了Q简单地看一看如何在E序中处理它们。用数据绑定,您已l徏立了时刻表的数据l构Q它由几U类型的 bean l成。处理数据的应用E序代码可以直接使用q些 bean?/p>

比方_假设您要查看在西雅图和洛杉矶之间有哪些航班可供选择Qƈ且要求班具备指定的最低品质评L别。清?9 l出了用数据绑?bean l构获取q些信息的基本代码(完整的细节请参阅?参考资?/a>下蝲的源文gQ?


清单 9. 航班查找E序代码
private static void listFlights(TimeTableBean top, String from,
            String to, int rating) {
            // find the routes for outbound and inbound flights
            Iterator r_iter = top.getRoutes().iterator();
            RouteBean in = null;
            RouteBean out = null;
            while (r_iter.hasNext()) {
            RouteBean route = (RouteBean)r_iter.next();
            if (route.getFrom().getIdent().equals(from) &&
            route.getTo().getIdent().equals(to)) {
            out = route;
            } else if (route.getFrom().getIdent().equals(to) &&
            route.getTo().getIdent().equals(from)) {
            in = route;
            }
            }
            // make sure we found the routes
            if (in != null && out != null) {
            // find outbound flights meeting carrier rating requirement
            Iterator o_iter = out.getFlights().iterator();
            while (o_iter.hasNext()) {
            FlightBean o_flight = (FlightBean)o_iter.next();
            if (o_flight.getCarrier().getRating() >= rating) {
            // find inbound flights meeting carrier rating
            //  requirement, and leaving after outbound arrives
            int time = timeToMinute(o_flight.getArrivalTime());
            Iterator i_iter = in.getFlights().iterator();
            while (i_iter.hasNext()) {
            FlightBean i_flight = (FlightBean)i_iter.next();
            if (i_flight.getCarrier().getRating() >= rating
            &&
            timeToMinute(i_flight.getDepartureTime())
            > time) {
            // list the flight combination
            printFlights(o_flight, i_flight, from, to);
            }
            }
            }
            }
            }
            }
            

您可以尝试用前?清单 8中的数据。如果您询问从西雅图QSEAQ到z杉ӞLAXQ、别大于或{于 8 的班机,׃得到如下的结果:

Leave SEA on Arctic Airlines 426 at 6:23a
            return from LAX on Arctic Airlines 593 at 9:27a
            Leave SEA on Arctic Airlines 426 at 6:23a
            return from LAX on Arctic Airlines 102 at 12:30p
            Leave SEA on Arctic Airlines 433 at 9:00a
            return from LAX on Arctic Airlines 102 at 12:30p

与文档模型的比较

q里我不准备全面讨论使用 XML 文档模型的等价代码,那太复杂了,以单独成章。解册个问题最单的方式Q可能是首先解析 carrier 元素Q创建每个标识符代码到相应对象之间的映射链接。然后用和 清单 9中示例代码类似的逻辑。和使用 bean 的例子相比,每一步都更加复杂Q因Z码用的?XML 成分而不是真正的数据倹{性能可能更糟——只Ҏ据进行少量的操作q不是问题Q但是如果数据处理是应用E序的核心,q就会成Z个主要的焦点?

如果?bean ?XML 的映中使用更多的数据类型{换,差别会更大(无论从代码的复杂性还是从性能的角度看Q。比方说Q假设您使用很多的航班时_可能希望把文本时间{化成一U更好的国际化表C(如一天内的分钟数Q参?清单 9Q。您可以选择为文本和国际化格式定义可以替换的 get ?set ҎQ让映射仅仅使用文本形式Q,也可以定义一个定制的 org.exolab.castor.mapping.FieldHandler 实现?Castor 使用q些倹{保留时间值的内部形式Q可以避免匹配清?9 中的航班时进行{换,也许q能加快处理速度?

除了本文中所q的之外—?FieldHandler 只是一个例子,Castor q有许多qh的特性。但愿这些例子和讨论使您能够初步领略q个框架的强大功能和灉|性?我相信,您将和我一样发?Castor 非常有用也非常有?





回页?/strong>


l束?/span>

对于使用 XML 交换数据的应用程序,数据l定是文档模型很好的替代品。它化了~程Q因为您不必再按?XML 的方式思考。相反,您可以直接用代表应用程序所用数据含义的对象。与文档模型相比Q它q潜在地提供了更好的内存和处理器使用效率?/p>

本文中,我?Castor 框架展示了一些越来越复杂的数据绑定的例子。所有这些例子都使用所谓的 直接数据l定Q开发h员根据数据定义类Q然后把数据映射?XML 文档l构。下一文章中Q我探讨另一U方法: 模式数据l定Q利用模式(?DTD、XML 模式或者其他的cdQ生成和那个模式对应的代码?

Castor 同时支持模式Ҏ和本文中介绍的直接绑定,您将在以后看到更多的 Castor 应用。我q关注着 JSR-031 Java 数据l定标准的进展,q对q些Ҏ的性能q行比较。更多了?Java 中的 XML 数据l定q个领域Q请速来讉KL最q的 IBM developerWorks?



]]>
使用Castor XMLhttp://www.tkk7.com/lcwlv929/articles/145061.html?/dc:creator>?/author>Fri, 14 Sep 2007 02:18:00 GMThttp://www.tkk7.com/lcwlv929/articles/145061.htmlhttp://www.tkk7.com/lcwlv929/comments/145061.htmlhttp://www.tkk7.com/lcwlv929/articles/145061.html#Feedback0http://www.tkk7.com/lcwlv929/comments/commentRss/145061.htmlhttp://www.tkk7.com/lcwlv929/services/trackbacks/145061.html一??br /> Castor XML是一UXML数据l定框架?br /> XML的另外两U主要APIQDOM和SAXQDocument Object Model和Simple API for XMLQ,主要是从l构的角度去处理XML文gQ而Castor XML是以对象的模式去处理XML文档中的数据

大多数情况下Q{换框枉过ClassDescriptor和FieldDescriptor来描q{换时所需要的信息?/p>

二?转换框架
转换框架中最主要的两个类是:org.exolab.castor.xml.Marshaller和org.exolab.castor.xml.Unmarshaller

marshal: Marshaller.marshal(obj,writer);
unmarshal: Unmarshaller.unmarshal(Person.class,reader);

上面的这U{换方式,只适合于按照默认方式进行{化,如果要用映文Ӟ需要采用以下方式?br /> marshalQ?br /> Mapping mapping = new Mapping();
mapping.loadMapping(“mapping.xml”);
Marshaller marshaller = new Marshaller(writer);
marshaller.setMapping(mapping);
marshaller.marshal(obj);
Marshaller?个marshalҎ中,只有marshal(Object obj)q个Ҏ不是静态的Q其他的四个都是静态的marshal(obj,writer), marshal(obj,handler), marshal(obj,node)

unmarshalQ?br /> Mapping mapping = new Mapping();
mapping .loadMapping(“mapping.xml”);
Unmarshaller unm = new Unmarshaller(“Person.class”);//使用Person.class作ؓ构造Unmarshaller的参?br /> unm.setMapping(mapping);
Person person = (Person)unm.unmarshal(reader);
Unmarshaller中,object可以从reader中{换而来Q也可以从source、node转换而来Q静态方法均是两个参敎ͼ非静态方法都是一个来源作为参数?/p>

三?使用存在的Class和对?br /> Castor几乎可以Q何对象和XMLq行转换。当指定class的描q文件不存在Ӟ转换框架使用默认的reflection机制来获得对象的信息?/p>

转化对象存在的主要约束是Q?br /> q些class必须有一个public而且default的构造函敎ͼ必须有adequate get/setҎ?/p>

四?cLq符(ClassDescriptor)
org.exolab.castor.xml.XMLClassDescriptor
cLq符提供转换时所需的必要信息。ClassDescriptor不仅可以用于Castor XMLQ还可以用于Castor JDO

cLq符包括一l字D|q符(FieldDescriptor)

cLq符通常情况下有四种创徏方式Q两U在~译?效率较高)Q两U在q行?较ؓ方便)
~译时描q符Q?br /> 1. 让需要被describe的类实现org.exolab.castor.xml.XMLClassDescriptor接口
2. 使用Source Code Generator创徏合适的descriptor
q行时描q符Q?br /> 3. 默认Q用Castor的introspect机制
4. 提供mapping文gQ或者默认和配置文gq用

使用”default introspection”机制必须为每一个要转换的field配备对应的get/setҎQ?br /> 如果没有get/setҎQ但是是public的fieldQ也可以以direct field access的方式被转换Q?br /> 但是如果一个类中ؓ有的成员定义了get/setҎQ即使其他成员是public的,也不会被转换Q?br /> 自动内省机制是自动触发的。可以通过castor.properties文g控制自动转换的特性,比如改变名称转换、基本型别是转换为attributeq是element{?/p>

Mapping文g也可以用来描q要被{换的cRmapping的装载发生在marshal和unmarshal之前Qorg.exolab.castor.mapping.MappingQ?/p>

]]>
Hibernate.cfg.xml配置文ghttp://www.tkk7.com/lcwlv929/articles/133538.html?/dc:creator>?/author>Tue, 31 Jul 2007 03:47:00 GMThttp://www.tkk7.com/lcwlv929/articles/133538.htmlhttp://www.tkk7.com/lcwlv929/comments/133538.htmlhttp://www.tkk7.com/lcwlv929/articles/133538.html#Feedback0http://www.tkk7.com/lcwlv929/comments/commentRss/133538.htmlhttp://www.tkk7.com/lcwlv929/services/trackbacks/133538.html <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN" "hibernate-configuration-2.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- properties -->
        <!-- jndi -->
        <property name="connection.datasource">java:comp/env/jdbc/quickstart</property>
        <property name="connection.provider_class">net.sf.hibernate.connection.DatasourceConnectionProvider</property>
        <property name="dialect">net.sf.hibernate.dialect.SQLServerDialect</property>
        <!-- jdbc
        <property name="connection.url">jdbc:microsoft:sqlserver://localhost:1433;SelectMethod=cursor;DatabaseName=pubs</property>
        <property name="connection.driver_class">com.microsoft.jdbc.sqlserver.SQLServerDriver</property>
        <property name="connection.username">sa</property>
        <property name="connection.password"></property>
         -->
        <property name="jdbc.fetch_size">50</property><!-- 一ơ读的数据库记录?-->
        <property name="jdbc.batch_size">30</property><!-- 讑֮Ҏ据库q行扚w删除 -->
        <property name="show_sql">true</property><!-- Hibernate发送给数据库的sql昄出来 -->
        <!-- Mapping files -->
        <mapping resource="cat.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

数据库表主键的知识点Q?br>Generator 为每?POJO 的实例提供唯一标识。一般情况,我们使用“native”。class 表示采用q成器接口net.sf.hibernate.id.IdentifierGenerator 实现的某个实例,其中包括Q?/p>

“assigned”
主键由外部程序负责生成,?save() 之前指定一个?/p>

“hilo”
通过hi/lo 法实现的主键生成机Ӟ需要额外的数据库表或字D|供高位值来源?/p>

“seqhilo”
与hilo cMQ通过hi/lo 法实现的主键生成机Ӟ需要数据库中的 SequenceQ适用于支?Sequence 的数据库Q如Oracle?/p>

“increment”
主键按数值顺序递增。此方式的实现机制ؓ在当前应用实例中l持一个变量,以保存着当前的最大|之后每次需要生成主键的时候将此值加1作ؓ主键。这U方式可能生的问题是:不能在集下使用?/p>

“identity”
采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL 中的主键生成机制?/p>

“sequence”
采用数据库提供的 sequence 机制生成主键。如 Oralce 中的Sequence?/p>

“native”
?Hibernate Ҏ使用的数据库自行判断采用 identity、hilo、sequence 其中一U作Z键生成方式?


“uuid.hex”
?Hibernate Z128 ?UUID 法 生成16 q制数|~码后以长度32 的字W串表示Q作Z键?/p>

“uuid.string”
与uuid.hex cMQ只是生成的主键未进行编码(长度16Q,不能应用?PostgreSQL 数据库中?/p>

“foreign”
使用另外一个相兌的对象的标识W作Z键?/p>

以下举例Q?br>1、指定参数的情况Q?br>    <id name="id" unsaved-value="0">
      <generator class="sequence">
        <param name="sequence">SEQ_CHILD</param>
      </generator>
</id>
使用的是sequenceQ适合oracle数据库;


2、对于sql server2000中的数据库子增字D?在配|文件用下列方法实玎ͼ
<id name="id" type="long" unsaved-value="0">
     <column name="id" sql-type="numeric" not-null="true" />
     <generator class="identity" />
</id>
q里主要?identity:代表由sql server2000数据库自己提供子增字D?如果要hibernate自己提供,则用increment关键字来实现


3、如果表中的主键用字W串cd:可以用hibernate自己提供的方法实C键唯一:
  <id name="id" type="string" unsaved-value="null">
      <column name="cid" sql-type="char(32)" not-null="true" />
      <generator class="uuid.hex" />
  </id>
使用的是uuid.hex: 采用128位的法来生成一?2位字W串。最通用的一U方式。适用于所有数据库?/p>

重要的知识点:
1. 如果有部门表,有员工表,员工表中有dep_id,则表部门cd员工cLone-to-many的关p?
   可以使用:  ( 在部门类department中用下?
   Departmentc? 
     /**  部门的所有员?nbsp;  */
    private Set staffs = new TreeSet();
   
    xml的文?
      <set name="staffs" >
          <key column="dep_id"/>
          <one-to-many class="hbp.sys.data.Staff"/>
      </set>
      如果是list,需要用索引<index> </index>,具体其中的含?不是很明?待以后研I?br>     
 2. 如果部门要有一个负责h,即部门表(tb_department)中有一个字D?staff_id.
     那么表示部门和负责h之间的关pLmany-to-one的关p?br>     Departmentc?
      /** 部门负责人id */
    private Staff staff;
   
    xml 文g
     <many-to-one name="staff" class="hbp.sys.data.Staff"  column="staff_id"/> 
 
 3. 多对多关p?一般我们是做一个中间关联表.我用角色和权限做了个例子,
      Right(id,name)     Role(id,name)   中间?tb_role_right(role_id,right_id)
      RightcM有一个Role的集?private Set roles=new TreeSet();
      RolecM也有一个Right的集?private Set rights=new TreeSet();
      则两者是明显的多对多关系.使用many-to-many来实?
      xml文g?br>      right.hbm.xml:如下:
        <set name="roles" table="tb_role_right" cascade="all">
           <key column="right_id"/>
           <many-to-many column="role_id" class="hbp.sys.data.Role"/>
        </set>
      role.hbm.xml文g中类?
        <set name="rights" table="tb_role_right" cascade="all">
          <key column="role_id"/>
          <many-to-many column="right_id" class="hbp.sys.data.Right"/>
        </set>


4. 几个值得注意的问?
        a)在xml?映射文g?写类的名字时一定用cȝ全名:??cd?(hbp.sys.data.Staff),q个错误使我费了半天?:(
        b)我在写实现基本DAO操作?写了
             session.delete("from Right as right where right.id="+id); 
             E序L报错,我折腾了半天,跟踪到底,才恍然大?hibernate在解析sql语句的时候把
             其中的right,当成了数据库中的双?"保留?),?q种关键?不能随便用啊,:)


5. hibernate中HQL语言的查询根据你的sql的不同而返回不同的对象cd.
         如果你用session.find(String hql)
         一般会q回一个List,?from Staff staff;q回的是包含所有的员工对象的集?br>         如你的hql?select count(*) from Staff staff;则返回的是一个Integer对象
         如果你用的hql?select count(distinct staff.name),count(*) from Staff staff;则返回的是一个Object
         即Object[],需要先把他转换成Object[],然后在取[0],[1].
         q种设计我不知道hibernate是如何处理的,感觉既好也不?好的是可以用一个find获得L查询
         不好在于Ҏhql来处理返回结?Ҏ出错.



]]>
վ֩ģ壺 ߾Ʒۿѹۿ| ޾ƷӰԺ| ҹһƵ| ޹˾þһҳ| AV˾Ʒ߹ۿ| ͼƬС˵| ѿһ߳ëƬ| 182tvƵ߹ۿ| ߹ۿ| պƷһ | þþþ޾Ʒ| ۺɫĻ| Ƶ߹ۿ| ƬƵ| avr| avһ| òƵѹۿ| պƷӰһ| ҹһӰԺ| һỵĺʹȫƵƵ߹ۿ| ˳ɾƷƵ| Ļ| ƷAV鶹| avһ| ޾Ʒmv߹ۿ| ɫƷһ| ŷa߹ۿ| պƷһ| ޾Ʒպav| 182tvƵ·һ| ߾Ʒһ| Ƶ߹ۿ| 99ƵƷѹۿ7| ޺Ļ| Ƶֻ߹ۿַ| aëƬѧѹۿ| avԴվavַ| ƬվŮ| AVרƬ߹ۿ| 97Ƶ| պƷһҳһ|