Hibernate

Hibernate XML映射

第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>

<component name="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">

<customer id="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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值