Hibernate 关联关系映射 -双向关联

 

双向关联(Bidirectional associations)双方都持有对方的引用

 

一对多(one to many) / 多对一(many to one)

双向多对一关联 是最常见的关联关系。(这也是标准的父/子关联关系。)

一边是一对多,另一边是 多对一,分别编写。 

  
  
  
  
  1. <class name="Person"> 
  2.     <id name="id" column="personId"> 
  3.         <generator class="native"/> 
  4.     </id> 
  5.     <many-to-one name="address"  
  6.         column="addressId" 
  7.         not-null="true"/> 
  8. </class> 
  9.  
  10. <class name="Address"> 
  11.     <id name="id" column="addressId"> 
  12.         <generator class="native"/> 
  13.     </id> 
  14.     <set name="people" inverse="true"> 
  15.         <key column="addressId"/> 
  16.         <one-to-many class="Person"/> 
  17.     </set> 
  18. </class> 

 

create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )
 如果你使用List(或者其他有序集合类),你需要设置外键对应的key列为 not null,让Hibernate来从集合端管理关联,维护每个元素的索引(通过设置update="false" and insert="false"来对另一端反向操作)。 
   
   
   
   
  1. <class name="Person"> 
  2.    <id name="id"/> 
  3.    ... 
  4.    <many-to-one name="address" 
  5.       column="addressId" 
  6.       not-null="true" 
  7.       insert="false" --->多的一端不能插入、修改,只能用集合端管理关联,维护每个元素索引
  8.       update="false"/> 
  9. </class> 
  10.  
  11. <class name="Address"> 
  12.    <id name="id"/> 
  13.    ... 
  14.    <list name="people"> 
  15.       <key column="addressId" not-null="true"/> 
  16.       <list-index column="peopleIdx"/> 
  17.       <one-to-many class="Person"/> 
  18.    </list> 
  19. </class> 
 假若集合映射的<key>元素对应的底层外键字段是NOT NULL的,那么为这一key元素定义not-null="true"是很重要的。 不要仅仅为可能的嵌套<column>元素定义not-null="true"<key>元素也是需要的。 
     

 

所有的双向关联需要有一端被设置为inverse。在一对多关联中它必须是代表多(many)的那端。

而在多对多(many-to-many)关联中,你可以任意选取一端,因为两端之间并没有差别。

把关联的一端设置为inverse将告诉Hibernate忽略关联的这一端,把这端看成是另外一端的一个镜象(mirror)

由多的一端来 维护关联关系。。

但是上面有序集合List,是从集合端管理关联????一的一端 怎么没有inverse=“true”啊????????

 

单向1对多+单向多对1+inverse

 

一对一(one to one)

基于外键关联的双向一对一关联也很常见。

双向的和单向的差不多,就是在原来单向的基础上,在另一端加<one-to-one>

生成的数据库文件时完全一样的,只是hibernate在访问时发生了变化,可以双向查找、赋值

   
   
   
   
  1. <class name="Person"> 
  2.     <id name="id" column="personId"> 
  3.         <generator class="native"/> 
  4.     </id> 
  5.     <many-to-one name="address"  
  6.         column="addressId"  
  7.         unique="true" 
  8.         not-null="true"/> 
  9. </class> 
  10.  
  11. <class name="Address"> 
  12.     <id name="id" column="addressId"> 
  13.         <generator class="native"/> 
  14.     </id> 
  15.    <one-to-one name="person"  
  16.         property-ref="address"/> 
  17. </class> 
create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )

2、基于主键关联的一对一关联

需要使用特定的id生成器。

      
      
      
      
  1. <class name="Person"> 
  2.     <id name="id" column="personId"> 
  3.         <generator class="native"/> 
  4.     </id> 
  5.     <one-to-one name="address"/> 
  6. </class> 
  7.  
  8. <class name="Address"> 
  9.     <id name="id" column="personId"> 
  10.         <generator class="foreign"> 
  11.             <param name="property">person</param> 
  12.         </generator> 
  13.     </id> 
  14.     <one-to-one name="person"  
  15.         constrained="true"/> 
  16. </class> 
create table Person ( personId bigint not null primary key )
create table Address ( personId bigint not null primary key )
一对一 双向没有inverse。单向+<one-to-one.>

二、使用连接表的双向关联

(Bidirectional associations with join tables)

一对多(one to many) /多对一( many to one)

1、基于连接表的双向一对多关联

注意inverse="true"可以出现在关联的任意一端,即collection端或者join端。

  
  
  
  
  1. <class name="Person"> 
  2.     <id name="id" column="personId"> 
  3.         <generator class="native"/> 
  4.     </id> 
  5.     <set name="addresses"  
  6.         table="PersonAddress"> 
  7.         <key column="personId"/> 
  8.         <many-to-many column="addressId" 
  9.             unique="true" 
  10.             class="Address"/> 
  11.     </set> 
  12. </class> 
  13.  
  14. <class name="Address"> 
  15.     <id name="id" column="addressId"> 
  16.         <generator class="native"/> 
  17.     </id> 
  18.     <join table="PersonAddress"  
  19.         inverse="true"  
  20.         optional="true"> 
  21.         <key column="addressId"/> 
  22.         <many-to-one name="person" 
  23.             column="personId" 
  24.             not-null="true"/> 
  25.     </join> 
  26. </class> 

create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null, addressId bigint not null primary key )
create table Address ( addressId bigint not null primary key )

Person 中是一对多 所以有个<set> 集合, <key >-->personId ,对多 <many-to-many>+unique+

还要加个class

Address中是 多对一,用<join> 加个表,多对一是<many-to-one>

一对一(one to one)

基于连接表的双向一对一关联

极为罕见,但也是可行的。

  
  
  
  
  1. <class name="Person"> 
  2.     <id name="id" column="personId"> 
  3.         <generator class="native"/> 
  4.     </id> 
  5.     <join table="PersonAddress"  
  6.         optional="true"> 
  7.         <key column="personId"  
  8.             unique="true"/> 
  9.         <many-to-one name="address" 
  10.             column="addressId"  
  11.             not-null="true" 
  12.             unique="true"/> 
  13.     </join> 
  14. </class> 
  15.  
  16. <class name="Address"> 
  17.     <id name="id" column="addressId"> 
  18.         <generator class="native"/> 
  19.     </id> 
  20.     <join table="PersonAddress"  
  21.         optional="true" 
  22.         inverse="true"> 
  23.         <key column="addressId"  
  24.             unique="true"/> 
  25.         <many-to-one name="person" 
  26.             column="personId"  
  27.             not-null="true" 
  28.             unique="true"/> 
  29.     </join> 
  30. </class> 

create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null primary key, 
                                        addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )
  
  
  
  

多对多(many to many)

最后,还有 双向多对多关联.

   
   
   
   
  1. <class name="Person"> 
  2.     <id name="id" column="personId"> 
  3.         <generator class="native"/> 
  4.     </id> 
  5.     <set name="addresses"  table="PersonAddress"> 
  6.         <key column="personId"/> 
  7.         <many-to-many column="addressId" 
  8.             class="Address"/> 
  9.     </set> 
  10. </class> 
  11.  
  12. <class name="Address"> 
  13.     <id name="id" column="addressId"> 
  14.         <generator class="native"/> 
  15.     </id> 
  16.     <set name="people" inverse="true"  table="PersonAddress"> 
  17.         <key column="addressId"/> 
  18.         <many-to-many column="personId" 
  19.             class="Person"/> 
  20.     </set> 
  21. </class> 

create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId bigint not null, 
                                 addressId bigint not null, primary key (personId, addressId) )
create table Address ( addressId bigint not null primary key )

 

你可能感兴趣的:(Hibernate)