19.2. XML 映射元数据

优质
小牛编辑
131浏览
2023-12-01

许多 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"/>
            
    <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
>

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

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

返回的数据集将是这样:


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

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


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