双向多对一关联 是最常见的关联关系。(这也是标准的父/子关联关系。)
一边是一对多,另一边是 多对一,分别编写。
- <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>
- <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"
andinsert="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元素定义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在访问时发生了变化,可以双向查找、赋值
- <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 )2、基于主键关联的一对一关联
需要使用特定的id生成器。
- <class name="Person">
- <id name="id" column="personId">
- <generator class="native"/>
- </id>
- <one-to-one name="address"/>
- </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>
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端。
- <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>
- <join table="PersonAddress"
- inverse="true"
- optional="true">
- <key column="addressId"/>
- <many-to-one name="person"
- column="personId"
- not-null="true"/>
- </join>
- </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>
基于连接表的双向一对一关联
极为罕见,但也是可行的。
- <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 )多对多(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>
- <set name="people" inverse="true" table="PersonAddress">
- <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 )