hibernate关联映射-双向

8.4. 双向关联(Bidirectional associations)


8.4.1. 一对多(one to many)/多对一(many to one)
双向多对一关联 是最常见的关联关系。下面的例子解释了这种标准的父/子关联关系。
模型:多个人(Person)对应一个地址(Address)。
实体:
public class Person1nfk_sx implements Serializable {
    private int personid;
    private String name;
    private int age;
    private Address1nfk_sx address1nfk_sx;
 
public class Address1nfk_sx implements Serializable {
    private int addressid;
    private String addressdetail;
    private Set Person=new HashSet();
映射:
<class name="Person">
<id name="id" column="personId">
<generator class="native"/>

</id>

<!--映射关联属性,column属性指定外键列名-->

<many-to-one name="address"
column="addressId"
not-null="true"/>

</class>

<class name="Address">

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

</id>

<!--映射集合属性,关联到持久化类--> <!--column用于指定外键列名-->

<set name="people" inverse="true">

<key column="addressId"/>

<!--映射关联类-->

<one-to-many class="Person"/>
</set>
</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" 和 insert="false" 来对另一端反向操作。
<class name="Person">
<id name="id"/>
<many-to-one name="address"
column="addressId"
not-null="true"
insert="false"
update="false"/>
</class>

<class name="Address">
<id name="id"/>
<list name="people">
<key column="addressId" not-null="true"/>
<list-index column="peopleIdx"/>
<one-to-many class="Person"/>
</list>
</class>
假若集合映射的 <key> 元素对应的底层外键字段是 NOT NULL 的,那么为这一 key 元素定义 notnull="
true" 是很重要的。不要仅仅为可能的嵌套 <column>元素定义 not-null="true",<key> 元素
也是需要的。

8.4.2. 一对一(One-to-one)

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

模型:一个地址对应一个人。

实体:

public class Person implements java.io.Serializable {

   private Long id;
   private String name;
   private Address address;
 
public class Address implements java.io.Serializable {
   private Long id;
   private Person person;
   private String detail;

映射:
<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>
<one-to-one name="person"
property-ref="address"/>
</class>
create table Person ( personId bigint not null primary key, addressId bigint not null unique )
create table Address ( addressId bigint not null primary key )

基于主键关联的一对一关联需要使用特定的 id 生成器:

模型:一个人对应一个地址。

实体: 

映射:
<class name="Person">

<id name="id" column="personId">
<generator class="native"/>

</id>

<!-- cascade="all":在保存person对象的时候,级联保存person对象关联的address对象    -->

<one-to-one name="address"/>
</class>

<class name="Address">

<id name="id" column="personId">

<!-- class="foreign": 一对一主键映射中,使用另外一个相关联的对象的标识符 -->

<generator class="foreign">
<param name="property">person</param>
</generator>

</id>

<!-- 表示在address表存在一个外键约束,外键参考相关联的表person -->

<one-to-one name="person"
constrained="true"/>
</class>
create table Person ( personId bigint not null primary key )

create table Address ( personId bigint not null primary key )

alter table address add constraint FK_Reference_2 foreign key (id)

references person (id) on delete restrict on update restrict;

8.5. 使用连接表的双向关联(Bidirectional associationswith join tables)
8.5.1. 一对多(one to many)/多对一(many to one)

下面是一个基于连接表的双向一对多关联的例子。注意 inverse="true" 可以出现在关联的任意一端,即 collection 端或者 join 端。

模型:一个人(Person)对应多个地址(Address)。

实体:

public class Person1ntab_sx {
    private int personid;
    private String name;
    private int age;
    private Set addresses=new HashSet();
 
public class Address1ntab_sx {
    private int addressid;
    private String addressdetail;
    private Person1ntab_sx person1ntab_sx;

映射:

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

</id>

<!--映射集合属性,关联到持久化类-->

<!--table="PersonAddress"指定了连接表的名字-->

<set name="addresses" table="PersonAddress">

<!--column="personid"指定连接表中关联当前实体类的列名-->

<key column="personId"/>

<!--unique="true"表示当前实体类是"1",不是"n"-->

<many-to-many column="addressId" unique="true" class="Address"/>
</set>
</class>

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

</id>

<!--映射关联属性,column属性指定外键列名-->
<join table="PersonAddress" inverse="true" optional="true">

<key column="addressId"/>
<many-to-one name="person"
column="personId"
not-null="true"/>
</join>
</class>
连接表中多方(address)还有1方(person)引用
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 )

8.5.2. 一对一(one to one)

基于连接表的双向一对一关联也是可行的,但极为罕见。

模型:一个人对应一个地址。

实体:

public class Person11tab_sx {
    private int personid;
    private String name;
    private int age;
    private Address11tab_sx address11tab_sx;
 
public class Address11tab_sx {
    private int addressid;
    private String addressdetail;
    private Person11tab_sx person11tab_sx;
 
映射:

<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>
<join table="PersonAddress"
optional="true"
inverse="true">
<key column="addressId"
unique="true"/>
<many-to-one name="person"
column="personId"
not-null="true"
unique="true"/>
</join>
</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 )

8.5.3. 多对多(many-to-many)

下面是一个双向多对多关联的例子。

模型:一个人可对应多个地址,一个地址也可以对应多个人。

实体:

public class Personnn_sx {
    private int personid;
    private String name;
    private int age;
    private Set addresses=new HashSet();
 
public class Addressnn_sx {
    private int addressid;
    private String addressdetail;
    private Set persons = new HashSet();

映射:

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

</id>

<!--映射集合属性,关联到持久化类-->

<!--table="PersonAddress"指定了连接表的名字-->

<set name="addresses" table="PersonAddress">
<!--column="personid"指定连接表中关联当前实体类的列名-->

<key column="personId"/>

<!--column="addressid"是连接表中关联本实体的外键-->

<many-to-many column="addressId"
class="Address"/>
</set>
</class>

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

</id>

<!--table="PersonAddress"是双向多对多的连接表-->
<set name="people" inverse="true" table="PersonAddress">

  <!--column="addressid"是连接表中关联本实体的外键-->

<key column="addressId"/>
<many-to-many column="personId"
class="Person"/>
</set>
</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 )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值