6.4. 集合例子(Collection example)

在前面的几个章节的确非常令人迷惑。 因此让我们来看一个例子。这个类:

  1. package eg;
  2. import java.util.Set;
  3. public class Parent {
  4. private long id;
  5. private Set children;
  6. public long getId() { return id; }
  7. private void setId(long id) { this.id=id; }
  8. private Set getChildren() { return children; }
  9. private void setChildren(Set children) { this.children=children; }
  10. ....
  11. ....
  12. }

这个类有一个Child的实例集合。如果每一个子实例至多有一个父实例, 那么最自然的映射是一个one-to-many的关联关系:

  1. <hibernate-mapping>
  2. <class name="Parent">
  3. <id name="id">
  4. <generator class="sequence"/>
  5. </id>
  6. <set name="children">
  7. <key column="parent_id"/>
  8. <one-to-many class="Child"/>
  9. </set>
  10. </class>
  11. <class name="Child">
  12. <id name="id">
  13. <generator class="sequence"/>
  14. </id>
  15. <property name="name"/>
  16. </class>
  17. </hibernate-mapping>

在以下的表定义中反应了这个映射关系:

  1. create table parent ( id bigint not null primary key )
  2. create table child ( id bigint not null primary key, name varchar(255), parent_id bigint )
  3. alter table child add constraint childfk0 (parent_id) references parent

如果父亲是必须的, 那么就可以使用双向one-to-many的关联了:

  1. <hibernate-mapping>
  2. <class name="Parent">
  3. <id name="id">
  4. <generator class="sequence"/>
  5. </id>
  6. <set name="children" inverse="true">
  7. <key column="parent_id"/>
  8. <one-to-many class="Child"/>
  9. </set>
  10. </class>
  11. <class name="Child">
  12. <id name="id">
  13. <generator class="sequence"/>
  14. </id>
  15. <property name="name"/>
  16. <many-to-one name="parent" class="Parent" column="parent_id" not-null="true"/>
  17. </class>
  18. </hibernate-mapping>

请注意NOT NULL的约束:

  1. create table parent ( id bigint not null primary key )
  2. create table child ( id bigint not null
  3. primary key,
  4. name varchar(255),
  5. parent_id bigint not null )
  6. alter table child add constraint childfk0 (parent_id) references parent

另外,如果你绝对坚持这个关联应该是单向的,你可以对&lt;key&gt;映射声明NOT NULL约束:

  1. <hibernate-mapping>
  2. <class name="Parent">
  3. <id name="id">
  4. <generator class="sequence"/>
  5. </id>
  6. <set name="children">
  7. <key column="parent_id" not-null="true"/>
  8. <one-to-many class="Child"/>
  9. </set>
  10. </class>
  11. <class name="Child">
  12. <id name="id">
  13. <generator class="sequence"/>
  14. </id>
  15. <property name="name"/>
  16. </class>
  17. </hibernate-mapping>

另外一方面,如果一个子实例可能有多个父实例, 那么就应该使用many-to-many关联:

  1. <hibernate-mapping>
  2. <class name="Parent">
  3. <id name="id">
  4. <generator class="sequence"/>
  5. </id>
  6. <set name="children" table="childset">
  7. <key column="parent_id"/>
  8. <many-to-many class="Child" column="child_id"/>
  9. </set>
  10. </class>
  11. <class name="Child">
  12. <id name="id">
  13. <generator class="sequence"/>
  14. </id>
  15. <property name="name"/>
  16. </class>
  17. </hibernate-mapping>

表定义:

  1. create table parent ( id bigint not null primary key )
  2. create table child ( id bigint not null primary key, name varchar(255) )
  3. create table childset ( parent_id bigint not null,
  4. child_id bigint not null,
  5. primary key ( parent_id, child_id ) )
  6. alter table childset add constraint childsetfk0 (parent_id) references parent
  7. alter table childset add constraint childsetfk1 (child_id) references child

更多的例子,以及一个完整的父/子关系映射的排练,请参阅第 21 章 示例:父子关系(Parent Child Relationships).

甚至可能出现更加复杂的关联映射,我们会在下一章中列出所有可能性。