hibernate-orm/doc/reference/fr/modules/xml.xml

293 lines
9.7 KiB
XML
Raw Normal View History

<?xml version="1.0" encoding="iso-8859-1"?>
<chapter id="xml">
<title>Mapping XML</title>
<para><emphasis>
Notez que cette fonctionnalit<69> est exp<78>rimentale dans Hibernate 3.0 et
est en d<>veloppement extr<74>mement actif.
</emphasis></para>
<sect1 id="xml-intro" revision="1">
<title>Travailler avec des donn<6E>es XML</title>
<para>
Hibernate vous laisse travailler avec des donn<6E>es XML persistantes de la
m<>me mani<6E>re que vous travaillez avec des POJOs persistants. Un arbre XML
peut <20>tre vu comme une autre mani<6E>re de repr<70>senter les donn<6E>es relationnelles
au niveau objet, <20> la place des POJOs.
</para>
<para>
Hibernate supporte dom4j en tant qu'API pour la manipulation des arbres XML.
Vous pouvez <20>crire des requ<71>tes qui r<>cup<75>rent des arbres dom4j <20> partie de la
base de donn<6E>es, et avoir toutes les modifications que vous faites sur l'arbre
automatiquement synchronis<69>es dans la base de donn<6E>es. Vous pouvez m<>me prendre
un document XML, l'analyser en utilisant dom4j, et l'<27>crire dans la base de
donn<6E>es via les op<6F>rations basiques d'Hibernate :
<literal>persist(), saveOrUpdate(), merge(), delete(), replicate()</literal>
(merge() n'est pas encore support<72>).
</para>
<para>
Cette fonctionnalit<69> a plusieurs applications dont l'import/export de donn<6E>es,
l'externalisation d'entit<69>s via JMS ou SOAP et les rapports XSLT.
</para>
<para>
Un simple mapping peut <20>tre utilis<69> pour simultan<61>ment mapper les propri<72>t<EFBFBD>s
d'une classe et les noeuds d'un document XML vers la base de donn<6E>es, ou,
si il n'y a pas de classe <20> mapper, il peut <20>tre utilis<69> juste pour mapper
le XML.
</para>
<sect2 id="xml-intro-mapping">
<title>Sp<EFBFBD>cifier le mapping XML et le mapping d'une classe ensemble</title>
<para>
Voici un exemple de mapping d'un POJO et du XML simultan<61>ment :
</para>
<programlisting><![CDATA[<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>]]></programlisting>
</sect2>
<sect2 id="xml-onlyxml">
<title>Sp<EFBFBD>cifier seulement un mapping XML</title>
<para>
Voici un exemple dans lequel il n'y a pas de class POJO :
</para>
<programlisting><![CDATA[<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>]]></programlisting>
<para>
Ce mapping vous permet d'acc<63>der aux donn<6E>es comme un arbre dom4j, ou comme
un graphe de paire nom de propri<72>t<EFBFBD>/valeur (<literal>Map</literal>s java). Les
noms des propri<72>t<EFBFBD>s sont des constructions purement logiques qui peuvent <20>tre
r<>f<EFBFBD>r<EFBFBD>es des dans requ<71>tes HQL.
</para>
</sect2>
</sect1>
<sect1 id="xml-mapping" revision="1">
<title>M<EFBFBD>tadonn<EFBFBD>es du mapping XML</title>
<para>
Plusieurs <20>l<EFBFBD>ments du mapping Hibernate acceptent l'attribut <literal>node</literal>.
Ceci vous permet de sp<73>cifier le nom d'un attribut XML ou d'un <20>l<EFBFBD>ment qui
contient la propri<72>t<EFBFBD> ou les donn<6E>es de l'entit<69>. Le format de l'attribut
<literal>node</literal> doit <20>tre un des suivants :
</para>
<itemizedlist spacing="compact">
<listitem>
<para><literal>"element-name"</literal> - mappe vers l'<27>l<EFBFBD>ment XML nomm<6D></para>
</listitem>
<listitem>
<para><literal>"@attribute-name"</literal> - mappe vers l'attribut XML nomm<6D></para>
</listitem>
<listitem>
<para><literal>"."</literal> - mappe vers le parent de l'<27>l<EFBFBD>ment</para>
</listitem>
<listitem>
<para>
<literal>"element-name/@attribute-name"</literal> -
mappe vers l'<27>l<EFBFBD>ment nomm<6D> de l'attribut nomm<6D>
</para>
</listitem>
</itemizedlist>
<para>
Pour des collections et de simples associations valu<6C>es, il y a un attribut
<literal>embed-xml</literal> suppl<70>mentaire. Si <literal>embed-xml="true"</literal>,
qui est la valeur par d<>faut, l'arbre XML pour l'entit<69> associ<63>e (ou la collection
des types de valeurs) sera embarqu<71>e directement dans l'arbre XML pour l'entit<69> qui
poss<73>de l'association. Sinon, si <literal>embed-xml="false"</literal>, alors
seule la valeur de l'identifiant r<>f<EFBFBD>renc<6E> appara<72>tra dans le XML pour de simples
associations de points, et les collections n'appra<72>tront simplement pas.
</para>
<para>
Vous devriez faire attention <20> ne pas laisser <literal>embed-xml="true"</literal>
pour trop d'associations, puisque XML ne traite pas bien les liens circurlaires.
</para>
<programlisting><![CDATA[<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>]]></programlisting>
<para>
dans ce cas, nous avons d<>cid<69> d'embarquer la collection d'identifiants de compte,
mais pas les donn<6E>es actuelles du compte. La requ<71>te HQL suivante :
</para>
<programlisting><![CDATA[from Customer c left join fetch c.accounts where c.lastName like :lastName]]></programlisting>
<para>
devrait retourner l'ensemble de donn<6E>es suivant :
</para>
<programlisting><![CDATA[<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>]]></programlisting>
<para>
Si vous positionnez <literal>embed-xml="true"</literal> sur le mapping
<literal>&lt;one-to-many&gt;</literal>, les donn<6E>es pourraient
ressembler plus <20> <20>a :
</para>
<programlisting><![CDATA[<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>]]></programlisting>
</sect1>
<sect1 id="xml-manipulation" revision="1">
<title>Manipuler des donn<6E>es XML</title>
<para>
Relisons et mettons <20> jour des documents XML dans l'application. Nous faisons
<20>a en obtenant une session dom4j :
</para>
<programlisting><![CDATA[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();]]></programlisting>
<programlisting><![CDATA[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();]]></programlisting>
<para>
Il est extr<74>mement utile de combiner cette fonctionnalit<69> avec l'op<6F>ration
<literal>replicate()</literal> d'Hibernate pour impl<70>menter des imports/exports
de donn<6E>es XML.
</para>
</sect1>
</chapter>