Hibernate 学习经验之谈-(四)关联映射
来源:互联网 发布:知乎2016 编辑:程序博客网 时间:2024/05/22 17:48
摘要:
(待编写)
Hibernate 是一个ORM 框架,它的重点就是对象之间的关系模型,维护对象之间的关系是hibernate 的核心内容,也是这个框架中相对比较难的一点。如果能够灵活地运用好这个框架,必须熟悉对象之间的联系。Hibernate 中的主要有三种对象的关系:One to One(一对一关联映射);One to Many (一对多关联映射);Many to Many (关联映射)。 每一种映射又分单向和双向。在数据库中关系表之间的关系只有一种,就是外键关联,hibernatre的对象映射就是建立在数据库外键关联之上。
要掌握hibernate的关联映射,必须要分析hibernate 在使用对象关联时生成的DDL语句,理解每一种映射在数据库中的对应处理方式。
单向关联与双向关联的区别
对象通过组合的方式来表达的类之间的关系,并在hbm文件或者注解上做出明确的说明。
单向可以理解为在两个有关联的对象实体中,只在一方中说明关联关系,对象只能在一方导向到另一方。
双向可以理解为在两个有关联的对象实体中,双方都有说明关联关系的配置,对象之间可以互相访问到对方。
导向的意思是说在对象的关联字段访问到关联的对象的信息,双向和单向在数据库层级的实现基本一样。
对于设置了双向关联的实体,最好的做法就是在其中一方使用mappedBy 指定主导关系,不然会出现冗余的数据字段。原则是在1-1 可以任意设一方,1-N 在N方设置mappedBy,N-N 的在任意一方设置。mappedBy 是关联注解的一个属性,mappedBy="xxx",xxx 为主导关系的getXXX对应的值。例如mappedBy=“person” person 对应的不是下文中的person 属性,而是对应getter 中getXXX,的“XXX”位置的值,person 对应getPerson();
一.One to One(一对一关联映射)
1.解析:
例如,一个人只能有一张身份证,一张身份证只能对应一个人;这两个对象之间就是属于一对一;一对一是三种关系中最简单的一种。
2.种类:主键关联,唯一外键关联;
2.1 主键关联:两个对象采用一样的主键值来表明他们之间是属于一对一的关系,这种方法是基本不用的。
2.2 外键关联:两个对象采用外键来表示两个之间的联系。
3.配置方式(只讲外键关联)
3.1单向配置
Person
package com.hwj.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.Table;import org.hibernate.annotations.DynamicUpdate;@Table(name="t_person")@Entity@DynamicUpdatepublic class Person {private int id;private String nickName;//关联字段private IDCard idCard;@Id@GeneratedValuepublic int getId() {return id;}@OneToOnepublic IDCard getIdCard() {return idCard;}public String getNickName() {return nickName;}public void setId(int id) {this.id = id;}public void setIdCard(IDCard idCard) {this.idCard = idCard;}public void setNickName(String nickName) {this.nickName = nickName;}}
IDCard
<pre name="code" class="java">package com.hwj.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.Table;import org.hibernate.annotations.DynamicUpdate;@Entity@Table(name="t_idcard")@DynamicUpdatepublic class IDCard {private int id;private String name;private String idNo;@Id@GeneratedValuepublic int getId() {return id;}public String getIdNo() {return idNo;}public String getName() {return name;}public void setId(int id) {this.id = id;}public void setIdNo(String idNo) {this.idNo = idNo;}public void setName(String name) {this.name = name;}}
hibernate 生成的sql语句
Hibernate: create table t_idcard ( id integer not null auto_increment, idNo varchar(255), name varchar(255), primary key (id) )Hibernate: create table t_person ( id integer not null auto_increment, nickName varchar(255), idCard_id integer, primary key (id) )Hibernate: alter table t_person add constraint FK_iwf0ex84epvoh2ndq1axpceg9 foreign key (idCard_id) references t_idcard (id)
3.2 双向配置
Person
package com.hwj.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.Table;import org.hibernate.annotations.DynamicUpdate;@Table(name="t_person")@Entity@DynamicUpdatepublic class Person {private int id;private String nickName;//关联字段private IDCard idCard;@Id@GeneratedValuepublic int getId() {return id;}@OneToOne(mappedBy="pserson")public IDCard getIdCard() {return idCard;}public String getNickName() {return nickName;}public void setId(int id) {this.id = id;}public void setIdCard(IDCard idCard) {this.idCard = idCard;}public void setNickName(String nickName) {this.nickName = nickName;}}
IDCard
package com.hwj.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.Table;import org.hibernate.annotations.DynamicUpdate;@Entity@Table(name="t_idcard")@DynamicUpdatepublic class IDCard {private int id;private String name;private String idNo;private Person pserson;@Id@GeneratedValuepublic int getId() {return id;}public String getIdNo() {return idNo;}public String getName() {return name;}@OneToOnepublic Person getPserson() {return pserson;}public void setId(int id) {this.id = id;}public void setIdNo(String idNo) {this.idNo = idNo;}public void setName(String name) {this.name = name;}public void setPserson(Person pserson) {this.pserson = pserson;}}
hibernate 生成的sql语句
Hibernate: create table t_idcard ( id integer not null auto_increment, idNo varchar(255), name varchar(255), pserson_id integer, primary key (id) )Hibernate: create table t_person ( id integer not null auto_increment, nickName varchar(255), primary key (id) )Hibernate: alter table t_idcard add constraint FK_pdvviqxfv7qwech66rqm08830 foreign key (pserson_id) references t_person (id)
总结,使用主要使用外键关联,在双方设置了双向关联的时候,进行mappedBy 设置。
二.One to Many 与 Many to One
其实一对多,还有多对一,都只是在不同的角度来看,但是映射产生的结果可能会不一样。这里使用Group 组与 User 成员来做举例。
1.单向映射
1.1 One to Many (一对多 )
Group 映射
package com.hwj.model;import java.util.List;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.JoinColumn;import javax.persistence.OneToMany;import javax.persistence.Table;import org.hibernate.annotations.DynamicUpdate;import org.hibernate.annotations.UpdateTimestamp;@Entity@Table(name="t_group")@DynamicUpdatepublic class Group {private int id;private String name;private List<User> users;@Id@GeneratedValuepublic int getId() {return id;}public String getName() {return name;}@OneToMany@JoinColumn(name="group_id")public List<User> getUsers() {return users;}public void setId(int id) {this.id = id;}public void setName(String name) {this.name = name;}public void setUsers(List<User> users) {this.users = users;}}
User 的映射
package com.hwj.model;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.ManyToOne;import javax.persistence.Table;import org.hibernate.annotations.DynamicUpdate;@Entity@Table(name="t_user")@DynamicUpdatepublic class User {private int id;private String name;@Id@GeneratedValuepublic int getId() {return id;}public String getName() {return name;}public void setId(int id) {this.id = id;}public void setName(String name) {this.name = name;}}
产生的sql语句
Hibernate: create table t_group ( id integer not null auto_increment, name varchar(255), primary key (id) )Hibernate: create table t_user ( id integer not null auto_increment, name varchar(255), group_id integer, primary key (id) )Hibernate: alter table t_user add constraint FK_e5f24mh6aryt9hsy99oydps6g foreign key (group_id) references t_group (id)
1.2.many to one
注:many to one 配置方式十分方便,只要在多的一方在关联字段加上 @ManyToOne 就可以正确在多一方生成外键约束。
2.双向关联
注;双向关联中需要在one 的一方设置mappedBy ,在many to one 的一方没有这个属性。设置完后就是实现了对数据的双向导航。
三.Many to Many (关联映射)
1.单向映射
只要在关联字段上添加@ManyToMany 就可以实现多对多单向映射。
2.双向映射
双向映射的时候一定要设置在任意一方设置mappedBy 这样才能不会执行重复的sql语句。
3.表生成
多对多表映射是采用中间表的方式来实现映射的,中间表字段的修改可以使用@JoinTable来实现。这个注解可以修改中间表的表名,表中的外键字段。
@JoinTable(
joinColumns={@JoinColumn(name="本对象的外键引用字段名")}, //为数组的原因是考虑到联合主键的情况
inverseJoinColumns={@JoinColumn(name="另外的一方的对象外键引用的字段名")} //为数组的原因是考虑到联合主键的情况
)
- Hibernate 学习经验之谈-(四)关联映射
- Hibernate映射解析——关联映射(四)
- 【hibernate】关联映射那些事(四)----继承映射
- Hibernate框架学习之四:关联映射那些事
- Hibernate学习手记(5)--关联映射
- 一步步学习Hibernate框架(四):采用jpa实现一对多关联映射(二)
- Hibernate学习20 -- 关联映射10 -- 组件映射(component)
- Hibernate 简单使用(四)一对多关联映射
- Hibernate关联映射学习笔记
- Hibernate学习---关联关系映射
- Hibernate学习笔记(3)---hibernate关联关系映射
- Hibernate(四):Hibernate映射——多对一单向关联映射
- 系统学习hibernate之四:hibernate多对一关联映射
- Hibernate学习之---Hibernate的关联映射
- 新手上路之Hibernate(四):单向一对一关联映射(主键、唯一外键关联)
- Hibernate映射详解(四)--一对一唯一外键关联映射
- 【SSH进阶之路】Hibernate映射——多对一单向关联映射(四)
- 【SSH进阶之路】Hibernate映射——多对一单向关联映射(四)
- 关于支付宝4.1.x以上不能支付的异常
- cpio建立、还原备份档
- 1012. The Best Rank (25)
- [Leetcode]Basic Calculator II
- Command /usr/bin/codesign failed with exit code 1
- Hibernate 学习经验之谈-(四)关联映射
- “奔跑吧,牛客“---统计一
- Algorithms—104.Maximum Depth of Binary Tree
- 【Mark】黑客与画家 - 第一章 为什么书呆子不受欢迎
- 鬼脚七 两个故事
- STM32 ST-LINK Utility无法下载的处理方法
- 引用形参使用中要注意的问题
- 多核程序设计——缓存一致性协议MESI
- 流程控制和类型转换