`
giga_Zhang
  • 浏览: 153439 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate关联关系映射探究(4-6)

阅读更多

4. Bidirectional associations

<o:p> </o:p>

4.1. one to many / many to one

A bidirectional many-to-one association is the most common kind of association. (This is the standard parent/child relationship.)

xml 代码
  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. <class name="Address">  
  10.      <id name="id" column="addressId">  
  11.           <generator class="native"/>  
  12.      </id>  
  13.      <set name="people" inverse="true">  
  14.           <key column="addressId"/>  
  15.           <one-to-many class="Person"/>  
  16.      </set>  
  17. </class>  
sql 代码
  1. create table Person ( personId bigint not null primary key, addressId bigint not null )  
  2. create table Address ( addressId bigint not null primary key )  

If you use a List (or other indexed collection) you need to set the key column of the foreign key to not null,and let Hibernate manage the association from the collections side to maintain the index of each element (making the other side virtually inverse by setting update="false"and insert="false"):

xml 代码
  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. <class name="Address">  
  11.      <id name="id"/>  
  12.           ...   
  13.      <list name="people">  
  14.           <key column="addressId" not-null="true"/>  
  15.           <list-index column="peopleIdx"/>  
  16.           <one-to-many class="Person"/>  
  17.      </list>  
  18. </class>  

It is important that you define not-null="true"on the <key>element of the collection mapping if the underlying foreign key column is NOT NULL. Don't only declare not-null="true" on a possible nested <column> element, but on the <key>element.

4.2. one to one

A bidirectional one-to-one association on a foreign key is quite common.

xml 代码
  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. <class name="Address">  
  11.      <id name="id" column="addressId">  
  12.           <generator class="native"/>  
  13.      </id>  
  14.      <one-to-one name="person" property-ref="address"/>  
  15. </class>  
sql 代码
  1. create table Person ( personId bigint not null primary key, addressId bigint not null unique )  
  2. create table Address ( addressId bigint not null primary key )  

A bidirectional one-to-one association on a primary key uses the special id generator.

xml 代码
  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. <class name="Address">  
  8.      <id name="id" column="personId">  
  9.           <generator class="foreign">  
  10.                <param name="property">person</param>  
  11.           </generator>  
  12.      </id>  
  13.      <one-to-one name="person" constrained="true"/>  
  14. </class>  
sql 代码
  1. create table Person ( personId bigint not null primary key )   
  2. create table Address ( personId bigint not null primary key )  

5. Bidirectional associations with join tables

5.1. one to many / many to one

A bidirectional one-to-many association on a join table. Note that the inverse="true" can go on either end of the association, on the collection, or on the join.

xml 代码
  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.                unique="true"  
  9.                class="Address"/>  
  10.      </set>  
  11. </class>  
  12. <class name="Address">  
  13.      <id name="id" column="addressId">  
  14.           <generator class="native"/>  
  15.      </id>  
  16.      <join table="PersonAddress"  
  17.           inverse="true"  
  18.           optional="true">  
  19.           <key column="addressId"/>  
  20.           <many-to-one name="person"  
  21.                column="personId"  
  22.                not-null="true"/>  
  23.      </join>  
  24. </class>  
sql 代码
  1. create table Person ( personId bigint not null primary key )   
  2. create table PersonAddress ( personId bigint not null, addressId bigint not null primary key )  
  3. create table Address ( addressId bigint not null primary key )  

5.2. one to one

A bidirectional one-to-one association on a join table is extremely unusual, but possible.

xml 代码
  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" unique="true"/>  
  8.           <many-to-one name="address"  
  9.                column="addressId"  
  10.                not-null="true"  
  11.                unique="true"/>  
  12.       </join>  
  13. </class>  
  14. <class name="Address">  
  15.      <id name="id" column="addressId">  
  16.           <generator class="native"/>  
  17.      </id>  
  18.      <join table="PersonAddress"  
  19.           optional="true"  
  20.           inverse="true">  
  21.           <key column="addressId" unique="true"/>  
  22.           <many-to-one name="person"  
  23.                column="personId"  
  24.                not-null="true"  
  25.                unique="true"/>  
  26.      </join>  
  27. </class>  
sql 代码
  1. create table Person ( personId bigint not null primary key )   
  2. create table PersonAddress ( personId bigint not null primary key, addressId bigint not null unique )  
  3. create table Address ( addressId bigint not null primary key )  

5.3. many to many

Finally, we have a bidirectional many-to-many association.

xml 代码
  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. <class name="Address">  
  12.      <id name="id" column="addressId">  
  13.           <generator class="native"/>  
  14.      </id>  
  15.      <set name="people" inverse="true" table="PersonAddress">  
  16.      <key column="addressId"/>  
  17.      <many-to-many column="personId"  
  18.           class="Person"/>  
  19.      </set>  
  20. </class>  
sql 代码
  1. create table Person ( personId bigint not null primary key )   
  2. create table PersonAddress ( personId bigint not null, addressId bigint not nullprimary key (personId, addressId) )  
  3. create table Address ( addressId bigint not null primary key )  

6. More complex association mappings

More complex association joins are extremely rare. Hibernate makes it possible to handle more complex situations using SQL fragments embedded in the mapping document. For example, if a table with historical account information data defines accountNumber, effectiveEndDate and effectiveStartDatecolumns, mapped as follows:

xml 代码
  1. <properties name="currentAccountKey">  
  2. <property name="accountNumber" type="string" not-null="true"/>  
  3. <property name="currentAccount" type="boolean">  
  4. <formula>case when effectiveEndDate is null then 1 else 0 end</formula>  
  5. </property>  
  6. </properties>  
  7. <property name="effectiveEndDate" type="date"/>  
  8. <property name="effectiveStateDate" type="date" not-null="true"/>  

Then we can map an association to the current instance (the one with null effectiveEndDate) using:

xml 代码
  1. <many-to-one name="currentAccountInfo"  
  2.      property-ref="currentAccountKey"  
  3.      class="AccountInfo">  
  4.      <column name="accountNumber"/>  
  5.      <formula>'1'</formula>  
  6. </many-to-one>  

In a more complex example, imagine that the association between Employeeand Organizationis maintained in an Employment table full of historical employment data. Then an association to the employee's most recent employer (the one with the most recent startDate) might be mapped this way:

xml 代码
  1. <join>  
  2.      <key column="employeeId"/>  
  3.           <subselect>  
  4.                Select employeeId, orgId   
  5.                from Employments   
  6.                group by orgId   
  7.                having startDate = max(startDate)   
  8.           </subselect>  
  9.      <many-to-one name="mostRecentEmployer"  
  10.           class="Organization"  
  11.           column="orgId"/>  
  12. </join>  

You can get quite creative with this functionality, but it is usually more practical to handle these kinds of cases using HQL or a criteria query.

分享到:
评论
1 楼 jinxilong123 2008-10-04  
      [u][/u]
引用
[flash=200,200][/flash][url][/url][img][/img]
引用
[i][/i][b][/b][flash=200,200][/flash][url][/url][img][/img]
引用
[/i][b][/b][i][u][/u]
引用
[img][/img][flash=200,200][/flash][/url][url]
[b][/b][/co[list=1]
[*]
[/list][img][/img][url][/url][flash=200,200][/flash][flash=200,200][/flash][flash=200,200][/flash][flash=200,200][/flash][flash=200,200][/flash][flash=200,200][/flash][flash=200,200][/flash][flash=200,200][/flash][flash=200,200][/flash][flash=200,200][/flash][url][/url][url][/url][img][/img][list=1]
[*]
[/list]
引用
[b][/b][i][/i][u][/u]
引用
引用
[url][/url]de]

相关推荐

Global site tag (gtag.js) - Google Analytics