1.3.2. 单向Set-based的关联
我们将向Person
类增加一连串的events。那样,通过调用aPerson.getEvents()
,就可以轻松地导航到特定person所参与的events,而不用去执行一个显式的查询。我们使用Java的集合类(collection):Set
,因为set 不包含重复的元素及与我们无关的排序。
我们需要用set 实现一个单向多值关联。让我们在Java类里为这个关联编码,接着映射它:
public class Person {
private Set events = new HashSet();
public Set getEvents() {
return events;
}
public void setEvents(Set events) {
this.events = events;
}
}
在映射这个关联之前,先考虑一下此关联的另外一端。很显然,我们可以保持这个关联是单向的。或者,我们可以在Event
里创建另外一个集合,如果希望能够双向地导航,如:anEvent.getParticipants()
。从功能的角度来说,这并不是必须的。因为你总可以显式地执行一个查询,以获得某个特定event的所有参与者。这是个在设计时需要做出的选择,完全由你来决定,但此讨论中关于关联的阶数是清楚的:即两端都是“多”值的,我们把它叫做多对多(many-to-many)关联。因而,我们使用Hibernate的多对多映射:
<class name="events.Person" table="PERSON">
<id name="id" column="PERSON_ID">
<generator class="native"/>
</id>
<property name="age"/>
<property name="firstname"/>
<property name="lastname"/>
<set name="events" table="PERSON_EVENT">
<key column="PERSON_ID"/>
<many-to-many column="EVENT_ID" class="events.Event"/>
</set>
</class>
Hibernate支持各种各样的集合映射,<set>
使用的最为普遍。对于多对多关联(或叫n:m实体关系), 需要一个关联表(association table)。表
里面的每一行代表从person到event的一个关联。表名是由set
元素的table
属性配置的。关联里面的标识符字段名,对于person的一端,是由<key>
元素定义,而event一端的字段名是由<many-to-many>
元素的column
属性定义。你也必须告诉Hibernate集合中对象的类(也就是位于这个集合所代表的关联另外一端的类)。
因而这个映射的数据库schema是:
_____________ __________________
| | | | _____________
| EVENTS | | PERSON_EVENT | | |
|_____________| |__________________| | PERSON |
| | | | |_____________|
| *EVENT_ID | <--> | *EVENT_ID | | |
| EVENT_DATE | | *PERSON_ID | <--> | *PERSON_ID |
| TITLE | |__________________| | AGE |
|_____________| | FIRSTNAME |
| LASTNAME |
|_____________|