您的位置:首页 > 其它

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

2012-11-02 16:05 375 查看
关联关系映射通常情况是最难配置正确的。在这个部分中,我们从单向关系映射开始,然后考虑双向关系映射,由浅至深讲述一遍典型的案例。在所有的例子中,我们都使用
Person
Address


我们根据映射关系是否涉及连接表以及多样性来划分关联类型。

一、单向关联(Unidirectional associations)一方持有另一方的引用

多对一(many to one)

单向many-to-one关联是最常见的单向关联关系。

<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</class>

<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
多的一方(Person),有一个字段(addressId)指向一的一方(Address)

[code]
create table Person ( personId bigint not null primary key, addressId bigint not null )
create table Address ( addressId bigint not null primary key )

一对一(one to one)

1、基于外键关联的单向一对一关联和单向多对一关联几乎是一样的。 唯一的不同就是单向一对一关联中的外键字段具有唯一性约束。 让多的一方变为 unique即可
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<many-to-one name="address"
column="addressId"
unique="true"
not-null="true"/>
</class>

<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>


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

addressId 为unique,所以只能属于一个 person

2、基于主键关联的单向一对一关联 通常使用一个特定的id生成器。(请注意,在这个例子中我们掉换了关联的方向。)(Address 持有Person对象)

[/code]
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
</class>

<class name="Address">
<id name="id" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<one-to-one name="person" constrained="true"/>
</class>

Address 没有自己的id生成器,只能用 Person类的主键。

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

一对多(one to many)

1、基于外键关联的单向一对多关联 是一种很少见的情况,并不推荐使用。一对多,需要在一的一方有 set<Address> addresses 属性 [code]<class name="Person"> <id name="id" column="personId"> <generator class="native"/> </id> <set name="addresses"> <key column="personId" not-null="true"/> <one-to-many class="Address"/> </set> </class> <class name="Address"> <id name="id" column="addressId"> <generator class="native"/> </id> </class>

在多的一方(Address) 增加了一个 指向一方(Person)的列(personId)

create table Person ( personId bigint not null primary key )
create table Address ( addressId bigint not null primary key, personId bigint not null )
[/code]
我们认为对于这种关联关系最好使用连接表。

注意:列都是增加在多的一方 *-to-many class="**"

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

(Unidirectional associations with join tables)

一对多(one to many)

基于连接表的单向一对多关联 应该优先被采用。

请注意,通过指定
unique="true"
,我们可以把多样性从多对多改变为一对多。

(many to one 指定unique=“true”,把多样性从多对一变为一对一

many to many 指定unique=“true”,把多样性从多对多变为 一对多)都把第一个many变为one

<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
unique="true"
class="Address"/>
</set>
</class>

<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>
[code]
create table Person ( personId bigint not null primary key )
create table PersonAddress ( personId not null, addressId bigint not null primary key )
create table Address ( addressId bigint not null primary key )


[/code]

多对一(many to one)

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

在关联关系可选的情况下应用也很普遍。

<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<join table="PersonAddress"
optional="true">
<key column="personId" unique="true"/>
<many-to-one name="address"
column="addressId"
not-null="true"/>
</join>
</class>

<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</class>


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

一对一(one to one)

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

非常少见,但也是可行的。

<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<join table="PersonAddress"
optional="true">
<key column="personId"
unique="true"/>
<many-to-one name="address"
column="addressId"
not-null="true"
unique="true"/>
</join>
</class>

<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</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)

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

<class name="Person">
<id name="id" column="personId">
<generator class="native"/>
</id>
<set name="addresses" table="PersonAddress">
<key column="personId"/>
<many-to-many column="addressId"
class="Address"/>
</set>
</class>

<class name="Address">
<id name="id" column="addressId">
<generator class="native"/>
</id>
</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 )

总结:

*-to-one 都没有指定 class 属性。*-to-many 都指定了 class 属性

<many-to-one name="address" -->属性
column="addressId"--->本表中增加 addressId 列
not-null="true"/> --->不为空

<one-to-one name="person" constrained="true"/> -->Address类中的 person属性

<one-to-many class="Address"/>

<many-to-many column="addressId" <one-to-many>,<many-to-many>都作为set的子元素出现,
因为是 to-many,对多。
他们都不是在本表中增加字段,要么在多方增加字段(无连接表时(通过<set>中的<key column>
添加),要么在连接表中增加字段(column属性添加))。
<one-to-many>很少用,只能用在无连接表的 一对多中,有连接表时是<many-to-many>。
都必须指定class属性,都紧跟着<key>
<many-to-many> 可以指定columu属性,在连接表中可以指定字段名

<one-to-many 依靠key指定属性,只用在无连接表中。


many-to-many 在<set 中指定table名

many-to-one 在<join table> 中指定table名
有连接表时 要么是 <many-to-many> 要么是<many-to-one>,通过增加或取消 unique属性,映射出多对多,一对多;
多对一,一对一;
<many-to-many> 可以对应 多对多,还可以对应 一对多。

<many-to-one> 可以对应 多对一,还可以对应 一对一。

有连接表 都有 <key column="" > 指定一个列名
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Hibernate