<many-to-one> 最简单的关联映射,就是many的一端外键引用one一端的主键
不需要你显式的在many的类中指定一个对应外键的属性,这个外键名是由标签中的column属性定义的,如果没有此属性,则默认的外键名就是实体属性名
<many-to-one> 标签内的cascade可以用来解决存储顺序的问题,解决级联操作。但是这个属性是属于hibernate管理的而不是数据库
有all,none,save-update,delete
——————————————————————————————————————————————————————
<one-to-one>一对一关联映射,有主键关联和唯一外键关联两种
比如person表和employee表要组成one-to-one关联映射
假设Person类中有属性employee
主键关联:不需要在表中增加额外的字段,因为是一个one的主键是外键引用另一端的one,那么这两个表中相对应的记录就使用同样的主键。在映射文件中,某一端的id生成策略必须是形如
这样就完成了从person到employee的单向one-to-one主键关联映射,可以在获取person的时候,加载到对应employee
如果要成为双向one-to-one主键关联映射,只需要在employee的类中同样加入属性person,并在映射文件中做如下one-to-one关联
因为person是外键引用的employee,因此这里就不需要constrainted属性了
one-to-one是唯一的默认具有级联操作的映射
唯一外键关联:
一端的映射:
<!-- 一对一唯一外键关联 在其中一端(添加字段的一端)说白了就是多对一的一种特殊形式,用unique属性保证多的一端只有一个属性,默认的外键引用的还是one一端的主键,many-to-one就是如此-->
<many-to-one name="employee" column="employeeid" unique="true"></many-to-one>
另一端的映射:
<!-- 注意这几个参数的意思,现在要实现双向一对一唯一外键关联映射,
必须通过property-ref来指定在另一端与本端关联的属性employee是Person类中对Employee的属性引用
因为这个是one-to-one标签,所以肯定是用的id-->
<one-to-one name="person" class="Person" property-ref="employee"></one-to-one>
——————————————————————————————————————————————————————
<one-to-many>
一对多关联映射,就是保证在加载one的一端的时候,能够将所有的many都加载上来
单向:
在程序里是在one的一端定义一个集合属性,用它来存放对many一端的所有引用
以Product和Part类来说明:
在Part一端,不需要特殊的设置
注意:一对多映射,它们之间的联系是由one的一端维护的(基于Hibernate的角度),所以有如下缺点:
第一,如上,not-null属性设置为“true”,因为外键是加载many一端的表中的,但是在many的映射中没有任何特殊的地方,所以它是不知道one的一端的,因此也无法得到one的一端的引用,所以如果设置not-null=“true”,会报错
第二,基于同样的理由,两者之间的关系,必须由one的一端来维护,所以如果many中增加了,必须发出update语句来维护多的一端,增加了维护成本
双向:
因为one-to-many单向映射的以上缺点,所以一般都将one-to-many置为双向,所谓双向就是:
* 在one的一端的集合上使用<key>,在对方表中加入一个外键指向one一端
* 在many一端采用<many-to-one>
注意: <key>标签指定的外键字段必须与<many-to-one>指定的外键字段一致,否则报引用错误
如果不设置inverse属性,则在one和many一端都可以维护这种关系,但是因为在one端维护的缺陷,所以使用inverse将one一端的维护责任屏蔽掉。
inverse反转:
即在存储的时候one的一端不再维护这种关系,就跟没有这种关系一样
程序里设进Set的many端对象相当于被忽略,不会发update语句,因此many端相关引用字段是空,如下:
有两种方式完成反转之后的工作:
第一,程序逻辑上,在many一端完全像many-to-one一样工作,如下:
————————————————————————————————————————————————————————————
<many-to-many>
多对多关联映射
第二,增加属性cascade
以上都是存储的问题,在读取的时候当然都可以读取上来many的数据,这是当然的否则这种映射就没意义了