考慮這麼一個物件類別:
User.java
package onlyfun.caterpillar;
public class User {
private String id;
private String name;
private char sex;
private int age;
private String address;
........
}
我們建立一個資料庫表格與這個類別作對應:
create table USER (
ID char(32) not null,
NAME varchar(16) not null,
SEX char(1),
AGE integer,
ADDRESS varchar(255) not null,
primary key (ID)
);
這樣的對應,您可以依照之前所介紹過的主題來撰寫映射文件達成,然而現在我們想要將address屬性以一個自訂物件Email表示,以便我們將這個自訂物件當作輔助物件,在適當的時候,我們可以直接呼叫Email物件的sendMail()方法,也就是說,我們的User類別變成:
User.java
package onlyfun.caterpillar;
public class User {
private String id;
private String name;
private char sex;
private int age;
private Email email;
public int getAge() {
return age;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public char getSex() {
return sex;
}
public Email getEmail() {
return email;
}
public void setAge(int i) {
age = i;
}
public void setId(String string) {
id = string;
}
public void setName(String string) {
name = string;
}
public void setSex(char c) {
sex = c;
}
public void setEmail(Email email) {
this.email = email;
}
}
而我們新增的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);
}
}
實際上,我們只是將使用者的Email資訊抽取出來,並獨立為一個輔助物件,這是為了在應用程式中操作方便而設計的,而實際上在資料庫表格中的資訊並沒有增加,我們不用改變資料表的內容。
顯然的,如果這麼設計,物件與資料表並不是一個對映一個,物件的數量將會比資料表來的多,物件的設計粒度比資料表來的細,為了完成物件與資料表的對應,在Hibernate中使用<component>標籤來進行設定,我們的User.hbm.xml映射文件撰寫如下:
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="string" unsaved-value="null">
<column name="ID" sql-type="char(32)"/>
<generator class="uuid.hex"/>
</id>
<property name="name" type="string" not-null="true">
<column name="NAME" length="16" not-null="true"/>
</property>
<property name="sex" type="char" column="SEX"/>
<property name="age" type="int" column="AGE"/>
<component name="email" class="onlyfun.caterpillar.Email">
<property name="address" type="string" column="ADDRESS" not-null="true"/>
</component>
</class>
</hibernate-mapping>
這個映射文件與之前的映射文件撰寫相比,主要是多了紅色的<component>部份,將Email類別當作User類別的一個組件(Component)。
接下來對物件的操作並沒有什麼太大的差別,例如下面的程式片段示範如何儲存資料:
User user = new User();
user.setName("caterpillar");
user.setSex('M');
user.setAge(28);
Email email = new Email();
email.setAddress("justin@caterpillar.onlyfun.net");
user.setEmail(email);
Session session = sessionFactory.openSession();
Transaction tx= session.beginTransaction();
session.save(user);
tx.commit();
session.close();
下面的程式片段則示範如何查詢資料:
Session session = sessionFactory.openSession();
List users = session.find("from User");
session.close();
for (ListIterator iterator = users.listIterator(); iterator.hasNext(); ) {
User user = (User) iterator.next();
System.out.println(user.getName() +
"/n/tAge: " + user.getAge() +
"/n/tSex: " + user.getSex());
user.getEmail().sendMail();
}
關於Component進一步的設定說明,可以看看參考手冊的5.1.12內容。