ITEEDU

Hibernate Gossip: 一对多

多对一 中,User对Room是多对一的关系,User实例维护着对Room实例的参考,如果将这个关系反过来,由Room实例维护对多个User实例的数据,就是一对多的关系。

具体来说,可以设计User类别如下:
User.java
package onlyfun.caterpillar;

public class User {
private Integer id;
private String name;

public User() {
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}
而在Room类别中,使用Set来记录多个User:
Room.java
package onlyfun.caterpillar; 

import java.util.Set;

public class Room {
private Integer id;
private String address;
private Set users;

public Room() {
}

public Integer getId() {
return id;
}
public void setId(Integer 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;
}

public void addUser(User user) {
users.add(user);
}

public void removeUser(User user) {
users.remove(user);
}
}
这种方式即所谓单向一对多关系,也就是Room实例知道User实例的存在,而User实例则没有意识到Room实例。

(在 多对一 中,则是单向多对一关系,即User知道Room的存在,但Room不知道User的存在。)

在映射文件上,先来看看User.hbm.xml:
User.hbm.xml
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="onlyfun.caterpillar.User" table="user">
<id name="id" column="id" type="java.lang.Integer">
<generator class="native"/>
</id>

<property name="name" column="name" type="java.lang.String"/>

</class>

</hibernate-mapping>
在单向关系中,被参考的对象其映像文件就如单一实体一样的配置,接下来看看Room.hbm.xml,使用<one-to-many>卷标配置一对多:
Room.hbm.xml
<?xml version="1.0" encoding="utf-8"?> 
<!DOCTYPE hibernate-mapping
PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>

<class name="onlyfun.caterpillar.Room" table="room">
<id name="id" column="id">
<generator class="native"/>
</id>

<property name="address"
column="address"
type="java.lang.String"/>

<set name="users" table="user" cascade="all">
<key column="room_id"/>
<one-to-many class="onlyfun.caterpillar.User"/>
</set>
</class>

</hibernate-mapping>
接着您可以如下储存对象:
User user1 = new User();
user1.setName("bush"); 
 
User user2 = new User(); 
user2.setName("caterpillar"); 
 
User user3 = new User(); 
user3.setName("momor"); 

Room room1 = new Room(); 
room1.setUsers(new HashSet());
room1.setAddress("NTU-M8-419");
room1.addUser(user1);
room1.addUser(user2);
        
Room room2 = new Room();
room2.setUsers(new HashSet());
room2.setAddress("NTU-G3-302");
room2.addUser(user3);

Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
 
session.save(room1);  // cascade 操作
session.save(room2); 
 
tx.commit();
session.close();
数据库中将储存以下的表格:
mysql> select * from user;
+----+--------------+-----------+
| id    | name         | room_id |
+----+-------------+------------+
|  1    | bush         |              1 |
|  2    | caterpillar |              1 |
|  3    | momor      |              2 |
+----+-------------+------------+
3 rows in set (0.01 sec)

mysql> select * from room;
+----+------------------+
| id    | address          |
+----+------------------+
|  1    | NTU-M8-419 |
|  2    | NTU-G3-302  |
+----+------------------+
2 rows in set (0.00 sec)