先前所介紹的集合映射都只使用了String屬性表示一個資料庫欄位的內容,在之前的一個主題中我們看過,我們可以將一個欄位的內容映射至一個Component物件:
入門 10 - Component 映射
如果我們想要將Component物件儲存至集合物件中,例如將Email物件儲存至HashSet中,在映射時只需要將<element> 標籤改為<composite-element>,並指定映射的類別,舉個實際的例子來說好了,我們撰寫以下的User類別,它的addrs 是HashSet,當中將儲存Email物件:
User.java
package onlyfun.caterpillar;
import java.util.HashSet;
import java.util.Set;
public class User {
private long id;
private String name;
private Set addrs = new HashSet();
public Set getAddrs() {
return addrs;
}
public void setAddrs(Set addrs) {
this.addrs = addrs;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void addAddress(Email addr) {
addrs.add(addr);
}
}
我們的Email類別如下:
Email.java
package onlyfun.caterpillar;
public class Email {
private String address;
public void setAddress(String address) {
this.address = address;
}
public String getAddress() {
return address;
}
public void sendMail() {
System.out.println("send mail to: " + address);
}
}
要映射這兩個類別,映射文件撰寫如下:
User.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class name="onlyfun.caterpillar.User" table="USER">
<id name="id" type="long" unsaved-value="null">
<column name="USER_ID"/>
<generator class="increment"/>
</id>
<property name="name" type="string" not-null="true">
<column name="NAME" length="16" not-null="true"/>
</property>
<set name="addrs" table="ADDRS">
<key column="USER_ID"/>
<composite-element class="onlyfun.caterpillar.Email">
<property name="address" column="ADDRESS" not-null="true"/>
</composite-element>
</set>
</class>
</hibernate-mapping>
您可以看到,實際上我們資料庫中的表格欄位是不變的,同樣是USER與ADDRS兩個表格,Hibernate所作的工作是在儲存資料或取出資料時,根據映射文件將ADDRS中的資料填入Email物件或取出。
類似的,您也可以使用Map物件來儲存Component,而映射文件中的<map>可以這麼撰寫:
<map name="files" table="FILES">
<key column="USER_ID"/>
<index column="DESCRIPTION" type="string"/>
<composite-element class="onlyfun.caterpillar.Files">
<property name="file" column="FILENAME" not-null=true/>
<property name="other" column="OTHER" not-null="true"/>
</composite-element>
</map>