在前一個主題中,User對Room是多對一,反過來看,Room對User是一對多,一個Room可以給多個User住宿使用,我們的User類別這次設計如下:
User.java
package onlyfun.caterpillar;
public class User {
private long id;
private String name;
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;
}
}
這次不在User中包括Room屬性,我們在Room類別中使用Set來儲存User,表示一個Room中所住宿的使用者:
Room.java
package onlyfun.caterpillar;
import java.util.*;
public class Room {
private long id;
private String address;
private Set users = new HashSet();
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Set getUsers() {
return users;
}
public void setUsers(Set users) {
this.users = users;
}
}
關於User的映射文件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" column="USER_ID">
<generator class="increment"/>
</id>
<property name="name">
<column name="NAME" length="16" not-null="true"/>
</property>
</class>
</hibernate-mapping>
而Room的映射文件Room.hbm.xml如下,我們使用<set>來作集合映射,而在當中使用<one-to-many>來指定Room對User的一對多關係:
Room.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.Room" table="ROOM">
<id name="id" column="ROOM_ID">
<generator class="increment"/>
</id>
<property name="address" type="string"/>
<set name="users" table="USER">
<key column="ROOM_ID"/>
<one-to-many class="onlyfun.caterpillar.User"/>
</set>
</class>
</hibernate-mapping>
我們使用下面這個程式來測試資料的儲存:
HibernateTest.java
import onlyfun.caterpillar.*;
import net.sf.hibernate.*;
import net.sf.hibernate.cfg.*;
public class HibernateTest {
public static void main(String[] args) throws HibernateException {
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Room room = new Room();
room.setAddress("NTU-M8-419");
User user1 = new User();
user1.setName("bush");
User user2 = new User();
user2.setName("caterpillar");
room.getUsers().add(user1);
room.getUsers().add(user2);
Session session = sessionFactory.openSession();
Transaction tx= session.beginTransaction();
session.save(user1);
session.save(user2);
session.save(room);
tx.commit();
session.close();
sessionFactory.close();
}
}
看看資料庫中實際儲存的內容:
mysql> select * from USER;
+---------+-------------+---------+
| USER_ID | NAME | ROOM_ID |
+---------+-------------+---------+
| 1 | bush | 1 |
| 2 | caterpillar | 1 |
+---------+-------------+---------+
2 rows in set (0.00 sec)
mysql> select * from ROOM;
+---------+------------+
| ROOM_ID | address |
+---------+------------+
| 1 | NTU-M8-419 |
+---------+------------+
1 row in set (0.00 sec)
在這邊我們先引出兩個主題,第一是每次我們都用save()儲存所有的暫存物件嗎?事實上我們只要透用Hibernate的「可達性」,上面的三行 save(),就可以簡化只save(room),而其所含的user1、user2也會自動儲存。第二是User與Room之間的關係我們到現在都只設計單向的,事實上我們會可以設計它們之間的雙向關聯。
這兩個主題都值得獨立一個探討,之後將會介紹。