Hibernate关联映射学习笔记

本文详细介绍了数据库中实体之间的关联映射,包括一对一、一对多、多对多等关系的实现方式及注意事项,同时解释了级联操作在关联管理中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

dynamic-update
dynamic-insert

<class
     <id column列名 length字段长度
     <type 类型转换
     <generator生存策略 class=increment集群环境下不能用
                                                  identity               mysql使用 
                                                  sequence          oracle使用
                                                  uuid               hibernate生成
                                                  native           根据数据库能力自动选择
                                                  foreign          外键
                                                  guid sqlserver和mysql使用
                                                  assigned          手动分配

Hibernate关联映射
先建立对象(领域)模型
N - 1 映射
例子:多用户User属于一个组Group
关联映射的本质:
将关联关系映射到数据库,所谓的关联管理是对象模型在内存中的一个或多个引用
N的一端
N的一段1的一端
<manay-to-one name="group" column="groupid" cascade="save-update">

维护了多指向1的关系

Group
persistent状态的对象再提交事务时不能引用transient对象,否则会产生TransientObjectException异常,除非设置了级联(cascade)
<many-to-one>会在N的一端加入一个外键,指向1的一端,这个外键是由<many-to-one>中的column属性定义的。
级联的含义,是对象的连锁操作。

1-1 映射
例子:一个人Person对应一个身份证IdCard
1的一端(副表)1的另一端(主表)

Person{id,name,idCard}

主键关联(双向):
<id name="id">
<generator class="foreign">
<param name="property">idCard</param>

<one-to-one name="idCard" constrained="true">

<one-to-one>标签含义,指示hibernate怎么加载它的关联对象(idCard),默认是通过主键加载

 constrained="true"表明当前主键存在一个约束,person的主键作为外键参照了idCard

t_peron表内不会出现idCard列,因为可以通过外键参照t_idcard获得

默认启用了cascade,因为副表主键生成依赖于主表

 

Person{id,name,idCard}

唯一外键关联(单向)
多对一的特例,只是限制了多的一端的外键唯一性约束

<id name="id">

    <generator class="native"/>

    <many-to-one name="idCard" unique="true"/>

 

Person{id,name,idCard}

唯一外键关联(双向)

在1的一端存有多得一端的引用

数据库表和唯一外键映射单向一样,只是在1的一端添加<many-to-one>指导hibernate以此字段查询副表

IdCard{id, cardId,person}

 

<one-to-one name="person"/>

 

 

 

t_idcard表内也不会出现person列

 

 

 

IdCard{id, cardId}

跟N-1相同

 

 

 

 

 

IdCard{id, cardId,person}

<one-to-one name="person" property-ref="idCard">

<one-to-one>默认通过主键查找,所以要用property-ref指示hibernate根据person的外键idCard来查找

 
1 - N 映射
N的一端1的一端
例子:一班级有多个学生

单向 Class-------->Student

Class{id,name,students(Set类型)}
在多的一端加入一个外键指向1的一端,维护的关系是多指向一。和一对多的策略一样,只是站在的角度不同
<id name="id">
    <generator class="native">
        <set name="students">
            <key column="classesid"/>
            <one-to-many class="com.xxx.Student"/>
这在1的一端维护关系的缺点:
    1.<key name="classid">不能配置not-null="true",因为在添加class记录时首先添加student,暂且将t_student中的classid置为null,然后再添加class记录,待class记录添加完成生成classid后,再将此classid更新到前面添加的student记录。如果设置的话将导致无法保存
    2.多的一端不维护关系,Student对象不知道自己属于哪个班级,所以要发出多余的update语句来更新关系
 
双向
Class{id,name,students(Set类型)}
1的一端
...和单向相同
<set name="students" inverse="true">
通常用多的一端来维护,让1的一端维护失效,使用inverse属性,结果为若保存classes,在添加完classid为null的student和classes记录本身之后,就不update学生的classesid字段了
这种情况下也有方法使1的一端也能维护,就是结合cascade属性
<set name="students" inverse="true" cascade="true">
这样的话在保存classes时会变成先保存classes记录,然后再保存student记录,不再有多余的update操作
    inverse是控制关联关系的方向
    cascade是产生操作上的连锁反应
 
 

 

Student{id,name}

 

 
 
 
 
 <many-to-one name="class" class="Class" column="classid" not-null="true">
 
t_student表中生成列classid作为外键参照t_class中的主键id
 
 
 
 
 
 
Student{id,name,classes}
<many-to-one name="classes" column="classid">
会在t_student表中加入名为classesid的列,该列名必须和1的一端配置的key列名一致
 
 
N - N 映射
N的一端N的一端
例子:用户和用户的角色
单向 User--------->Role
User{id,name,roles(Set类型)}
需要借助第三张表t_user_role来维护t_user表和t_role表的关系
 
 <class name="xxx.User" table="t_user">
        .....
        <set name="roles" table="t_user_role">
              <key clolumn="userid"/>
      <many-to-many class="xxx.Role" column="roleid"></..>
 t_user_role将使用userid和roleid联合主键,分别作为外键参考t_user和t_role表中的对应列
 
 双向 User<--------->Role
User{id,name,roles(Set)}
...和单向的相同




<key>中的

 

Role{id,name}


<class name="xxx.Role" table="t_role">

    <id name="id">

        <generator class="native"/>

        <property name="name"/>

 


Role(id,name,users(Set))

 ...
<set name="users" table="t_user_role" order-by="userid">
<key column="roleid"/>
<many-to-many class="xxx.User" column="userid"/>
 
 table属性必须和单向关联中的table属性值一致
<key>中的column和<many-to-many>中的column要和单向关联中的对应属性值一致
 
 
 
 
 
 
 
 
 

 


 

 




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值