Hibernate.org Community Documentation

- Zurück
- Weiter

## Kapitel 20. XML-Mapping

XML Mapping is an experimental feature in Hibernate 3.0 and is currently under active development.

## 20.1. Das Arbeiten mit XML-Daten

Hibernate allows you to work with persistent XML data in much the same way you work with persistent POJOs. A parsed XML tree can be thought of as another way of representing the relational data at the object level, instead of POJOs.

Hibernate unterstützt dom4j als API zur Verarbeitung von XML-Bäumen. Sie können Anfragen, die dom4j-Bäume von der Datenbank abrufen, schreiben, wobei alle Modifikationen am Baum automatisch mit der Datenbank synchronisiert werden. Sie können sogar ein XML-Dokument unter Verwendung von dom4j auf die Syntax prüfen und mittels Hibernates Grundvorgängen: `persist(), saveOrUpdate(), merge(), delete(), replicate()` ("Merging" wird noch nicht unterstützt) in die Datenbank schreiben.

Dieses Feature bietet zahlreiche Anwendungen einschließlich des Imports/Exports von Daten, Externalisierung von Entity-Daten via JMS oder SOAP und XSLT-basiertem Reporting.

A single mapping can be used to simultaneously map properties of a class and nodes of an XML document to the database, or, if there is no class to map, it can be used to map just the XML.

### 20.1.1. Spezifizierung des gemeinsamen Mappens von XML und Klasse

Hier ist ein Beispiel für das gleichzeitige Mappen eines POJO und XML:

    <class name="Account"

            table="ACCOUNTS"

            node="account">

        <id name="accountId"

                column="ACCOUNT_ID"

                node="@id"/>

        <many-to-one name="customer"

                column="CUSTOMER_ID"

                node="customer/@id"

                embed-xml="false"/>

        <property name="balance"

                column="BALANCE"

                node="balance"/>

        ...

    </class

    >

### 20.1.2. Spezifizierung des Mappens von nur XML

Dieses ist ein Beispiel ohne POJO-Klasse:

    <class entity-name="Account"

            table="ACCOUNTS"

            node="account">

        <id name="id"

                column="ACCOUNT_ID"

                node="@id"

                type="string"/>

        <many-to-one name="customerId"

                column="CUSTOMER_ID"

                node="customer/@id"

                embed-xml="false"

                entity-name="Customer"/>

        <property name="balance"

                column="BALANCE"

                node="balance"

                type="big_decimal"/>

        ...

    </class

    >

This mapping allows you to access the data as a dom4j tree, or as a graph of property name/value pairs or java `Map`s. The property names are purely logical constructs that can be referred to in HQL queries.

## 20.2. XML-Mapping Metadaten

A range of Hibernate mapping elements accept the `node` attribute. This lets you specify the name of an XML attribute or element that holds the property or entity data. The format of the `node` attribute must be one of the following:

- `"element-name"`: map to the named XML element

- `"@attribute-name"`: map to the named XML attribute

- `"."`: map to the parent element

- `"element-name/@attribute-name"`: map to the named attribute of the named element

For collections and single valued associations, there is an additional `embed-xml` attribute. If `embed-xml="true"`, the default, the XML tree for the associated entity (or collection of value type) will be embedded directly in the XML tree for the entity that owns the association. Otherwise, if `embed-xml="false"`, then only the referenced identifier value will appear in the XML for single point associations and collections will not appear at all.

Do not leave `embed-xml="true"` for too many associations, since XML does not deal well with circularity.

    <class name="Customer"

            table="CUSTOMER"

            node="customer">

        <id name="id"

                column="CUST_ID"

                node="@id"/>

        <map name="accounts"

                node="."

                embed-xml="true">

            <key column="CUSTOMER_ID"

                    not-null="true"/>

            <map-key column="SHORT_DESC"

                    node="@short-desc"

                    type="string"/>

            <one-to-many entity-name="Account"

                    embed-xml="false"

                    node="account"/>

        </map>

        <component name="name"

                node="name">

            <property name="firstName"

                    node="first-name"/>

            <property name="initial"

                    node="initial"/>

            <property name="lastName"

                    node="last-name"/>

        </component>

        ...

    </class

    >

In this case, the collection of account ids is embedded, but not the actual account data. The following HQL query:

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

would return datasets such as this:

    <customer id="123456789">

        <account short-desc="Savings"

    >987632567</account>

        <account short-desc="Credit Card"

    >985612323</account>

        <name>

            <first-name

    >Gavin</first-name>

            <initial

    >A</initial>

            <last-name

    >King</last-name>

        </name>

        ...

    </customer

    >

Wenn Sie die Einstellung `embed-xml="true"` im `<one-to-many>`-Mapping vornehmen, so sehen die Daten eher wie folgt aus:

    <customer id="123456789">

        <account id="987632567" short-desc="Savings">

            <customer id="123456789"/>

            <balance

    >100.29</balance>

        </account>

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

    >

## 20.3. Manipulation von XML-Daten

You can also re-read and update XML documents in the application. You can do this by obtaining a dom4j session:

    Document doc = ....;

    Session session = factory.openSession();

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

    Transaction tx = session.beginTransaction();

    List results = dom4jSession

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

        .list();

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

        //add the customer data to the XML 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 in the 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();

When implementing XML-based data import/export, it is useful to combine this feature with Hibernate's `replicate()` operation.

Copyright © 2004 Red Hat, Inc.

- ZurückKapitel 19. Das Filtern von Daten
- Nach oben
- Zum Anfang
- WeiterKapitel 21. Verbesserung der Performance