Hibernate关联映射
关联映射
这里的关联映射指的是对象之间的关系,并不是指数据库的关系,而是当对象之间处于下列关系之一时,数据库表该如何映射,编程上该如何处理
常见的映射
一对一:单向,双向
一对多:单向,双向(和多对一双向相同)
多对一:单向,双向(一对多双向和多对一双向是一样的)
多对多:单向,双向
1 一对一(单向)
基于外键关联映射
和单向多对一关联几乎是一样的。唯一不同的就是单向一对一关联中的外键字段具有唯一性约束。这种方法会在表中生成一个新的外键字段.如果不限制外字段的唯一性约束,就会导致产生多对一的关联. 指定多的一端unique="true",这样就限制了多的一端的多重性为一.
两个对象之间一对的关系,例如:Person(人)-IdCard(身份证)
有两种策略可以实现一对一的关联映射:
*主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联。如下图:
单向一对一主键关联例子连接
*唯一外键关联:外键关联,本来是用于多对一的配置,但是加上唯一的限制之后(采用<many-to-one>标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性为一),也可以用来表示一对一关联关系,其实它就是多对一的特殊情况。如下图:
注解版:
在主的一方 添加从的一方的 对象(主是从表,从是主表)
在对象的get方法前面添加@onetoone 和@joincolumn(外键名 可写可不写)指明数据库两表关联的字段名称(也可以不写)
XML
在外键里面加column="wifeid" unique="true"(主)
<class name="类名" >
<id name="属性名(id)">
<generator class="生成策略"></generator>
</id>
<property name="属性名" column="数据库中的列名(属性名与列名相同时,可不写)" />
<many-to-one name="属性名(对象)" column="外键名" unique="true" />
</class>
2 一对一(双向)
唯一外键关联映射
对比单向一对一映射,需要在IdCard加入<one-to-one>标签,它不影响,只影响加载。如下图:
注解版:
两边互加@OneToOne其从方需要在@OneToOn中添加mappedby(参数) 参数是另外一个类对象属性的名称
如@OneToOne(mappedBy="wife")引用属性
加上mappedBy属性后就可以在wife这一端告知这个关联是在wife属性上设置的.就不用管理wife这一端生成的husband的设置.生成的wife表格不会有husband字段
xml版:
name:相当于注解版的mappedby
3 组件映射
对象关系:一个对象是另一个对象的一部分
数据库表:是一张表
例:
对象模型
Husband(id,name,wife)
Wife(wifeName,wifeAge)
注解版:
在Wife类名上加@Embeddable
在Husband的wife属性上建立注解
@Embedded 表明该对象是从别的位置嵌入过来的,是不需要单独映射的表.
这种方式生成的表为husband(id,name,wifename,wifeage),不会生成wife表
xml版:
<class name="Husband" >
<id name="id">
<generator class="native"/>
</id>
<property name="name"></property>
<component name="wife">
<property name="wifeName"/>
<property name="wifeAge"/>
</component>
</class>
4 多对一(单向)
多对一关联映射原理:在多的一端加入一个外键,指向一的一端,如下图:
//注意在创建实体类属性时应尽量避免与SQL语句中的关键字重名.
多对一单向关联映射
实体模型(User多对一Group)
User(id,name,group)多
Group(id,groupname)一
Annotation配置
@Entity
@Table(name="t_group")//注意表名与SQL中关键字重名
只需要在多的一端User属性group进行注解配置
@ManyToOne
@JoinColumn(name=”groupId”)
XML配置
<many-to-one name="group" column="groupId" />
标签会在”多”的一端添加外键,相当于在数据库中添加外键
生成的表为user(id,name,groupid),t_group(id,groupname)
属性cascade
<many-to-one name="group" column="groupid" cascade="all"/>
取值all,none,save-update,delete,对象间的级联操作,只对增删改起作用.
在存储时User时,设置了cascade="all"会自动存储相应的t_group.而不用管user关联的对象(通常情况下会优先存储关联的对象,然后再存储user).
5 一对多(单向)
一对多关联映射和多对一关联映射原理是一致的,都是在多的一端加入一个外键,指向一的一端。如下图(学生和班级):
模型(group一对多user)
Group(id,name,users)一
User(id,name)多
设计时在一的这一端存在着多的集合,生成的数据库表通常是在多的一端生成外键.
Set<User> users=new HashSet<User>()
一对多单向外键关联映射
在一的这一端Group端users属性上进行注解配置
@OneToMany
@JoinColumn(name="groupId")(不可少的)
如果不指定生成的外键列@JoinColumn(name="groupId"),默认会生成多对多的关系,产生一张中间表.
规律:
单向时, 一方存在另一方的引用,数据库表中体现为外键.配置时一般只用配置一端.
双向时,双方互持对方的引用,要进行双向两端的配置.基于annotation的双向配置中,在一端配置好后,在另一端必须用指定mappedby属性.
关于一对多/多对一数据库设计时,总是在多的一端加外键.通常在多的一端指定生成的外键名称.
6 一对多/多对一双向关联
采用一对多双向关联映射的目的主要是为了主要是为了解决一对多单向关联的缺陷而不是需求驱动的
一对多与多对一的双向关联是同一种情况.
关系模型(group一对多user)
Group(id,name,users)一
User(id,name,group)多
Set<User> users=new HashSet<User>()
配置规则:一般以多的一端为主,先配置多的一端
在多的一端User端配置group
@ManyToOne
@JoinColumn(name="groupid")//加上User表中关联Group表的列名不加会默认生成一个列
在一的一端Group端配置时,在users只需要加个mappedBy="group"
@OneToMany(mappedBy="group")
XML配置
Group中
<set name="users">
<key column="groupId"/>
<one-to-many class="com.hibernate.User"/>
</set>
Group中
<set name="users">
<key column="groupId"/>
<one-to-many class="com.hibernate.User"/>
</set>
在User中
<many-to-one name="group" column="groupId"/>
务必确保在多的一端生成的生成的外键和一的一方生成的外键的名字相同,都为groupId.
————————————————
版权声明:本文为CSDN博主「qq_40115919」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_40115919/article/details/83513705