Hibernate中的关系可以分为:单向关系和双向关系。顾名思义说的是从一方是否可以访问另一方,对应到数据库中也就是根据一方的值是否也可以检索出另一方的值了。
单向关联可以分为:
<!--[if !supportLists]-->l <!--[endif]-->单向1-1
<!--[if !supportLists]-->l <!--[endif]-->单向1-N
<!--[if !supportLists]-->l <!--[endif]-->单向N-1
<!--[if !supportLists]-->l <!--[endif]-->单向N-N
双向关联可以分为:
<!--[if !supportLists]-->l <!--[endif]-->双向1-1
<!--[if !supportLists]-->l <!--[endif]-->双向1-N
<!--[if !supportLists]-->l <!--[endif]-->双向N-N
单向1-N:
一个老师对应多个学生,那么需要在老师的模型中定义一个set或者list集合来存储多个学生。
Xml配置:
<class name="Student" table="student">
<id name="stu_id" type="string">
<generator class="uuid"/>
</id>
<property name="stu_name" type="string"/>
</class>
<class name="Teacher" table="teacher">
<id name="tea_id" type="string">
<generator class="uuid"/>
</id>
<property name="tea_name" type="string"/>
<!—设置级联关系为全级联,即当这一方更新数据的时候,会影响另一方的数据 -->
<set name="students" cascade=”all”>
<!—key就是在student表中指定的外键 -->
<key column="dong"/>
<one-to-many class="Student"/>
</set>
</class>
生成的建表语句:
alter table student drop foreign key FK8FFE823B3010B624
drop table if exists student
drop table if exists teacher
create table student (stu_id varchar(255) not null, stu_name varchar(255), dong varchar(255), primary key (stu_id))
create table teacher (tea_id varchar(255) not null, tea_name varchar(255), primary key (tea_id))
alter table student add index FK8FFE823B3010B624 (dong), add constraint FK8FFE823B3010B624 foreign key (dong) references teacher (tea_id)
插入测试:
Hibernate: insert into teacher (tea_name, tea_id) values (?, ?)
Hibernate: insert into student (stu_name, stu_id) values (?, ?)
Hibernate: insert into student (stu_name, stu_id) values (?, ?)
Hibernate: insert into student (stu_name, stu_id) values (?, ?)
//当执行完插入的时候,要更新外键值
Hibernate: update student set dong=? where stu_id=?
Hibernate: update student set dong=? where stu_id=?
Hibernate: update student set dong=? where stu_id=?
查询测试:
//查询teacher表中的指定元素
Hibernate: select teacher0_.tea_id as tea1_1_0_, teacher0_.tea_name as tea2_1_0_ from teacher teacher0_ where teacher0_.tea_id=?
//输出teacher的id和name
402881e437a109780137a10979ac0001:dong
//查询student表中的内容
Hibernate: select students0_.dong as dong1_, students0_.stu_id as stu1_1_, students0_.stu_id as stu1_0_0_, students0_.stu_name as stu2_0_0_ from student students0_ where students0_.dong=?
//输出学生的数目
3
删除测试:
//查询指定的记录
Hibernate: select teacher0_.tea_id as tea1_1_0_, teacher0_.tea_name as tea2_1_0_ from teacher teacher0_ where teacher0_.tea_id=?
//查询该记录所级联的相关记录
Hibernate: select students0_.dong as dong1_, students0_.stu_id as stu1_1_, students0_.stu_id as stu1_0_0_, students0_.stu_name as stu2_0_0_ from student students0_ where students0_.dong=?
//更改其级联关系,使得要删除的指定记录变得可以删除
Hibernate: update student set dong=null where dong=?
//删除指定记录及其级联记录
Hibernate: delete from student where stu_id=?
Hibernate: delete from student where stu_id=?
Hibernate: delete from student where stu_id=?
Hibernate: delete from teacher where tea_id=?
单向N-1
Xml配置:
<class name="Student" table="student">
<id name="stu_id" type="string">
<generator class="uuid"/>
</id>
<property name="stu_name" type="string"/>
<many-to-one name="teacher" class="Teacher" column="teacher_id" cascade="all"/>
</class>
<class name="Teacher" table="teacher">
<id name="tea_id" type="string">
<generator class="uuid"/>
</id>
<property name="tea_name" type="string"/>
</class>
建表语句:
alter table student drop foreign key FK8FFE823BE8C01538
drop table if exists student
drop table if exists teacher
create table student (stu_id varchar(255) not null, stu_name varchar(255), teacher_id varchar(255), primary key (stu_id))
create table teacher (tea_id varchar(255) not null, tea_name varchar(255), primary key (tea_id))
alter table student add index FK8FFE823BE8C01538 (teacher_id), add constraint FK8FFE823BE8C01538 foreign key (teacher_id) references teacher (tea_id)
插入测试:
源代码:
session = sessionFactory.openSession();
tx = session.beginTransaction();
Teacher t = new Teacher();
t.setTea_name("hello");
Student st = new Student();
st.setStu_name("dong");
st.setTeacher(t);
Student st1 = new Student();
st1.setStu_name("jing");
st1.setTeacher(t);
session.save(st1);
session.save(st);
tx.commit();
//容易发现hibernate对此作了优化
Hibernate: insert into teacher (tea_name, tea_id) values (?, ?)
Hibernate: insert into student (stu_name, teacher_id, stu_id) values (?, ?, ?)
Hibernate: insert into student (stu_name, teacher_id, stu_id) values (?, ?, ?)
删除测试:
由于在多的一方设置的级联决定方,那么当删除一个student的时候,也就会删除对应的teacher,但是还有其他的student与该teacher对应,那么就会出现异常操作,所以很多时候是一的那一方设置cascade属性。
单向1-1
它有两种方法:1、将其看成1-N的特例,即在N的一段设置为unique=”true”即可;2、将两个表的主键设置为一样的,即一个表自动生成主键,另一个表的主键链接到该表的主键;3、外键关联。
第一种方法的配置和1-N的配置基本一样,只需要在<many-to-one>的标签中增加unique=”ture”这个属性即可。
下面来看第二种方法的配置:
<class name="Student" table="student">
<id name="stu_id" type="string">
<!-- 引用外键 -->
<generator class="uuid">
<param name="property">teacher</param>
</generator>
</id>
<property name="stu_name" type="string"/>
<!--由于该表的主键是靠其他表的主键生成,则此处必须增加constrained="true"属性 -->
<one-to-one name="teacher" constrained="true"/>
</class>
<class name="Teacher" table="teacher">
<id name="tea_id" type="string">
<generator class="uuid"/>
</id>
<property name="tea_name" type="string"/>
</class>
生成的SQL语句:
alter table student drop foreign key FK8FFE823BFAB829A6
drop table if exists student
drop table if exists teacher
create table student (stu_id varchar(255) not null, stu_name varchar(255), primary key (stu_id))
create table teacher (tea_id varchar(255) not null, tea_name varchar(255), primary key (tea_id))
alter table student add index FK8FFE823BFAB829A6 (stu_id), add constraint FK8FFE823BFAB829A6 foreign key (stu_id) references teacher (tea_id)
------------------------------------------------------------------------------------------------------------------
插入测试:
Hibernate: insert into teacher (tea_name, tea_id) values (?, ?)
Hibernate: insert into student (stu_name, stu_id) values (?, ?)
====================================================================
单向N-N
单向N-N的配置与单向1-N的配置极其相似,但是它默认情况下需要有一个中间表连接,下面看看实例吧:
Xml配置:
<class name="StudentInfo" table="student">
<id name="stu_id" type="string">
<generator class="uuid"/>
</id>
<property name="stu_name" type="string"/>
<!-- 中间表的名字 -->
<set name="courses" table="s_c">
<!-- 表中与该模型关联的外键 -->
<key column="stu_id"/>
<!-- 表中与另一个模型关联的外键及其所在类 -->
<many-to-many class="StudentCourse" column="course_id"/>
</set>
</class>
<class name="StudentCourse" table="course">
<id name="course_id" type="string">
<generator class="uuid"/>
</id>
<property name="course_name" type="string"/>
</class>
下面是生成的SQL建表语句:
alter table s_c drop foreign key FK1BB975DF8944D
alter table s_c drop foreign key FK1BB979FCE8E33
drop table if exists course
drop table if exists s_c
drop table if exists student
create table course (course_id varchar(255) not null, course_name varchar(255), primary key (course_id))
create table s_c (stu_id varchar(255) not null, course_id varchar(255) not null, primary key (stu_id, course_id))
create table student (stu_id varchar(255) not null, stu_name varchar(255), primary key (stu_id))
alter table s_c add index FK1BB975DF8944D (stu_id), add constraint FK1BB975DF8944D foreign key (stu_id) references student (stu_id)
alter table s_c add index FK1BB979FCE8E33 (course_id), add constraint FK1BB979FCE8E33 foreign key (course_id) references course (course_id)
--------------------------
插入测试:
Hibernate: insert into student (stu_name, stu_id) values (?, ?)
Hibernate: insert into course (course_name, course_id) values (?, ?)
Hibernate: insert into course (course_name, course_id) values (?, ?)
Hibernate: insert into student (stu_name, stu_id) values (?, ?)
Hibernate: insert into course (course_name, course_id) values (?, ?)
Hibernate: insert into s_c (stu_id, course_id) values (?, ?)
Hibernate: insert into s_c (stu_id, course_id) values (?, ?)
Hibernate: insert into s_c (stu_id, course_id) values (?, ?)
Hibernate: insert into s_c (stu_id, course_id) values (?, ?)
--------------------------
删除测试:
不能设置为全级联,否则当删除某一方的数据时,会将与其级联的另一方的数据删除,会影响中间连接表中其他的数据。
当然,除了上面在表内直接连接,还可以通过新建一个连接表,将两个表进行连接,此时所需要用到的标签就是<join>,join元素的table属性用于确定连接表的表名;使用key子元素来确定连接表外键,并且要为连接表增加一个many-to-one子元素,该子元素用于映射关联属性。
下面通过一个例子来描述一下其一般过程:
Xml配置文件:
<class name="Student" table="student">
<id name="stu_id" type="string">
<generator class="uuid"/>
</id>
<property name="stu_name" type="string"/>
<join table="join_table">
<key column="teacher_id"/>
<many-to-one name="teacher" cascade="all"/>
</join>
</class>
<class name="Teacher" table="teacher">
<id name="tea_id" type="string">
<generator class="uuid"/>
</id>
<property name="tea_name" type="string"/>
</class>
生成的SQL语句:
alter table join_table drop foreign key FK6F0A7479CE8CCB91
alter table join_table drop foreign key FK6F0A7479DA135E82
//多了一个连接表
drop table if exists join_table
drop table if exists student
drop table if exists teacher
//连接表中的内容也就是连接两个表的键值
create table join_table (teacher_id varchar(255) not null, teacher varchar(255), primary key (teacher_id))
//两个表无序另设外键
create table student (stu_id varchar(255) not null, stu_name varchar(255), primary key (stu_id))
create table teacher (tea_id varchar(255) not null, tea_name varchar(255), primary key (tea_id))
//将连接表与被连接的两个表进行关联
alter table join_table add index FK6F0A7479CE8CCB91 (teacher_id), add constraint FK6F0A7479CE8CCB91 foreign key (teacher_id) references student (stu_id)
alter table join_table add index FK6F0A7479DA135E82 (teacher), add constraint FK6F0A7479DA135E82 foreign key (teacher) references teacher (tea_id)
插入操作,此处插入的是两条记录:
Hibernate: insert into teacher (tea_name, tea_id) values (?, ?)
Hibernate: insert into student (stu_name, stu_id) values (?, ?)
Hibernate: insert into join_table (teacher, teacher_id) values (?, ?)
Hibernate: insert into student (stu_name, stu_id) values (?, ?)
Hibernate: insert into join_table (teacher, teacher_id) values (?, ?)
双向关联
其实所谓的双向关联,就是“站在自己的角度看关系”,例如:一个1-N的关系,如果我站在1的这一方,那么对于我而言,我和你就是1-N的关系;但是如果我站在N的这一方,那么对于我而言,我和你就是N-1的关系。那么其配置就和单向的一样了。
但是这样就会出现了一个问题,就是控制权的问题,也就是cascade要“听谁的话”的问题。还拿1-N的例子讲,我们可以在1的这一方生成多的这一方,也可以在N的这一方生成1的这一方,那么到底该如何的设置呢?
下面就简单看看这些问题。
双向1-N
Hibernate对于1-N的关联推荐使用双向关联,但不用1的这一端来控制关联关系,反而使用N的这一端来控制。例如:一个人可以对应多个地址,那么我们就可以用人控制地址。
双向1-1
<!--[if !supportLists]-->1、 <!--[endif]-->基于外键的双向1-1
基于外键的双向1-1关联,外键可以放在任意一边,在需要放外键的一段增加many-to-one元素。并且为many-to-one元素增加unique=”true”属性来表示1-1关联;并用name属性来指定关联属性的属性名。
另一端使用one-to-one元素,该元素使用name属性指定关联的属性名。为了让系统懂得不在为本表中增加一列,因此使用外键关联,用property-ref属性来引用关联类的自身属性。
<!--[if !supportLists]-->2、 <!--[endif]-->基于主键的双向1-1
两边都是one-to-one元素,需要在引用对方主键的那一端设置generator的class属性为foreign,并且其子标签param的name属性值为property,内容为与其关联的属性;还要为one-to-one元素设置属性constrained=”true”。
相关推荐
Hibernate对象关系映射一对多 很基础等文档
**二、Hibernate关系映射的类型** 1. **一对一(OneToOne)**: 表示一个实体对应另一个实体的唯一实例。这可以通过在两个类中都定义`@OneToOne`注解来实现,并通过`mappedBy`属性指定被引用的一方。 2. **一对多...
在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者将数据库操作转换为面向对象的方式,从而简化了数据访问层的编程。"hibernate关联关系映射"是Hibernate的核心概念之一,它定义了如何...
标题“Hibernate对象关系映射实例”表明我们将探讨的是使用Hibernate框架进行对象关系映射(ORM)的实际应用。ORM是将数据库表结构映射为Java类对象的一种技术,它使得开发者可以使用面向对象的方式来操作数据库,而...
Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用 Java 对象来操作数据库,消除了直接编写 SQL 的需要。在 Hibernate 中,映射关系是将数据库表与 Java 类之间的关联方式,使得对象模型可以与关系...
此外,自定义对象的映射是Hibernate映射中的一个重要部分。通过在实体类上使用@Entity注解,并使用@Id注解指定主键字段,可以将一个Java类映射到数据库的一张表。字段则通过@Column注解来指定列名和属性,如长度、...
Hibernate4中映射关系图解。
Hibernate实体关系映射
在Hibernate中,Set接口的实现类如HashSet和TreeSet通常用于一对多或多对多的关系映射。例如,一个用户可以有多个订单,订单也可以属于多个用户,这就形成了双向多对多关系。在映射文件中,我们通常使用`<set>`标签...
### Hibernate关系映射详解 #### 一、概述 Hibernate 是一款非常流行的 Java 持久层框架,它简化了对象关系映射 (Object Relational Mapping, ORM) 的过程,使得开发人员可以更加专注于业务逻辑的编写,而无需过多...
Hibernate关联关系映射.CHM Hibernate文档相关
Hibernate_关联关系映射配置详解,希望能帮助广大java爱好者
在本教程中,我们将深入探讨Hibernate中的一个关键概念——关系映射中的组件映射。Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,它允许开发人员以面向对象的方式处理数据库操作,极大地简化了数据层...
**标题:“Hibernate关系映射”** 在Java世界中,Hibernate是一个强大的对象关系映射(ORM)框架,它允许开发者将数据库操作转化为面向对象的方式,极大地简化了数据持久化的复杂性。"多对一"关系映射是Hibernate...
标题:“Hibernate继承关系映射.pdf” 描述:“简明扼要地介绍了Hibernate中继承关系的映射方式,深入探讨了三种不同的映射策略及其优缺点,同时解析了多态查询的概念。” 知识点: ### Hibernate继承关系映射...
关于Hibernate的基本数据类型与Java中基本数据类型的映射关系
Hibernate实体关系映射 一对一关系 一对多关系 多对多关系Hibernate实体关系映射
hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,hibernate,包含4个说明文档,分别详细解说了hibernate关联映射的关联关系,...
在Java的持久化框架Hibernate中,集合映射是将数据库中的表关系映射到对象的集合属性上,以便实现对象关系映射(ORM)。本文将深入探讨Hibernate中的四种主要集合映射类型:Set、List、Array和Map,以及它们在实际...