Hibernate

19 XML映射

注意这是Hibernate 3.0的一个实验性的特性。这一特性仍在积极开发中。

19.1. 用XML数据进行工作

Hibernate使得你可以用XML数据来进行工作,恰如你用持久化的POJO进行工作那样。解析过的XML树 可以被认为是另外一种在对象层面上代替POJO来表示关系型数据的途径.

Hibernate支持采用dom4j作为操作XML树的API。你可以写一个查询从数据库中检索出 dom4j树,随后你对这颗树做的任何修改都将自动同步回数据库。你甚至可以用dom4j解析一篇XML文档,然后使用Hibernate的任一基本操作将它写入数据库:persist(), saveOrUpdate(), merge(), delete(),replicate() (合并操作merge()目前还不支持)。

这一特性可以应用在很多场合,包括数据导入导出,通过JMS或SOAP表现实体数据以及 基于XSLT的报表。

一个单一的映射就可以将类的属性和XML文档的节点同时映射到数据库。如果不需要映射类, 它也可以用来只映射XML文档。

19.1.1. 指定同时映射XML和类

这是一个同时映射POJO和XML的例子:

<class name="Account"

       table="ACCOUNTS"

       node="account">


   <idname="accountId"

          column="ACCOUNT_ID"

          node="@id"/>


   <many-to-onename="customer"

           column="CUSTOMER_ID"

          node="customer/@id"

          embed-xml="false"/>


   <propertyname="balance"

          column="BALANCE"

          node="balance"/>


   ...


</class>

19.1.2. 只定义XML映射

这是一个不映射POJO的例子:

<class entity-name="Account"

       table="ACCOUNTS"

       node="account">


   <id name="id"

          column="ACCOUNT_ID"

           node="@id"

          type="string"/>


   <many-to-onename="customerId"

          column="CUSTOMER_ID"

          node="customer/@id"

          embed-xml="false"

          entity-name="Customer"/>


   <propertyname="balance"

          column="BALANCE"

           node="balance"

          type="big_decimal"/>


   ...


</class>

这个映射使得你既可以把数据作为一棵dom4j树那样访问,又可以作为由属性键值对(java Maps) 组成的图那样访问。属性名字是纯粹逻辑上的结构,你可以在HQL查询中引用它。

19.2. XML映射元数据

许多Hibernate映射元素具有node属性。这使你可以指定用来保存 属性或实体数据的XML属性或元素。node属性必须是下列格式之一:

"element-name" - 映射为指定的XML元素

"@attribute-name" - 映射为指定的XML属性

"." - 映射为父元素

"element-name/@attribute-name" - 映射为指定元素的指定属性

对于集合和单值的关联,有一个额外的embed-xml属性可用。 这个属性的缺省值是真(embed-xml="true")。如果embed-xml="true", 则对应于被关联实体或值类型的集合的XML树将直接嵌入拥有这些关联的实体的XML树中。 否则,如果embed-xml="false",那么对于单值的关联,仅被引用的实体的标识符出现在 XML树中(被引用实体本身不出现),而集合则根本不出现。

你应该小心,不要让太多关联的embed-xml属性为真(embed-xml="true"),因为XML不能很好地处理循环引用!

<class name="Customer"

       table="CUSTOMER"

       node="customer">


   <id name="id"

          column="CUST_ID"

          node="@id"/>


   <mapname="accounts"

           node="."

          embed-xml="true">

       <keycolumn="CUSTOMER_ID"

              not-null="true"/>

       <map-keycolumn="SHORT_DESC"

              node="@short-desc"

              type="string"/>

       <one-to-manyentity-name="Account"

              embed-xml="false"

              node="account"/>

   </map>


   <componentname="name"

          node="name">

       <propertyname="firstName"

              node="first-name"/>

       <propertyname="initial"

              node="initial"/>

       <propertyname="lastName"

              node="last-name"/>

   </component>


   ...


</class>

在这个例子中,我们决定嵌入帐目号码(account id)的集合,但不嵌入实际的帐目数据。下面的HQL查询:

from Customer c left join fetch c.accounts where c.lastName like :lastName

返回的数据集将是这样:

<customer id="123456789">

   <accountid="987632567" short-desc="Savings"/>

   <accountid="985612323" short-desc="Credit Card"/>

   <name>

      <first-name>Gavin</first-name>

      <initial>A</initial>

      <last-name>King</last-name>

   </name>

   ...

</customer>

如果你把一对多映射<one-to-many>的embed-xml属性置为真(embed-xml="true"), 则数据看上去就像这样:

<customer id="123456789">

   <accountid="987632567" short-desc="Savings">

       <customerid="123456789"/>

      <balance>100.29</balance>

   </account>

   <accountid="985612323" short-desc="Credit Card">

       <customerid="123456789"/>

      <balance>-2370.34</balance>

   </account>

   <name>

      <first-name>Gavin</first-name>

      <initial>A</initial>

      <last-name>King</last-name>

   </name>

   ...

</customer>

19.3. 操作XML数据

让我们来读入和更新应用程序中的XML文档。通过获取一个dom4j会话可以做到这一点:

Document doc = ....;


Session session = factory.openSession();

Session dom4jSession = session.getSession(EntityMode.DOM4J);

Transaction tx = session.beginTransaction();


List results = dom4jSession

   .createQuery("from Customerc left join fetch c.accounts where c.lastName like :lastName")

   .list();

for ( int i=0; i<results.size(); i++ ) {

   //add the customer data to theXML document

   Element customer = (Element)results.get(i);

   doc.add(customer);

}


tx.commit();

session.close();

Session session = factory.openSession();

Session dom4jSession = session.getSession(EntityMode.DOM4J);

Transaction tx = session.beginTransaction();


Element cust = (Element) dom4jSession.get("Customer",customerId);

for ( int i=0; i<results.size(); i++ ) {

   Element customer = (Element)results.get(i);

   //change the customer name inthe XML and database

   Element name =customer.element("name");

  name.element("first-name").setText(firstName);

  name.element("initial").setText(initial);

  name.element("last-name").setText(lastName);

}


tx.commit();

session.close();

将这一特色与Hibernate的replicate()操作结合起来而实现的基于XML的数据导入/导出将非常有用.




18 过滤数据

起始页

20 提升性能

来自:http://docs.huihoo.com/hibernate/reference-v3_zh-cn/xml.html


你可能感兴趣的:(Hibernate)