hibernate关联关系映射详解
词汇解释
关系:事物之间相互作用、相互联系的状态。范围最大。
联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n。
关联:表示对象之间的关系,既有数量性,又有方向性;动词:将对象之间通过某种方式联系起来。
映射:这里指java对象和数据库表的一种对应关系。动词:形成这种对应关系。
级联:有关系的双方中操作一方,另一方也将采取一些动作。
关联的联系种类
在不考虑关联的方向前提下,联系就是关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n。
一对一联系(1:1):如用户和身份证、一夫一妻
一对多联系(1:n):如班级和学生
多对多联系(m:n):如学生和选课
关联的方向
关联关系的方向可分为单向关联和双向关联。
双向关联的方向其实就不重要了,因为通过任一一方都可以维护彼此的关系。也就是说:在双向关联中一对多和多对一都是一样的。
单向关联
在关联标记例如<many-to-one>或者<one-to-many>,方向都是从左到右,换句话说是由左边维护它们的关系,参见下面例子。
假设存在两张表person表和address表,它们之间的联系是n:1;
即一个人的居住地址是唯一的,一个地址却可以多个人居住。
如果在应用的业务逻辑中,仅需要每个person实例能够查询得到其对应的Address实例,而Address实例并不需要查询得到其对应的person实例。
- <class name="Person" table="person">
- <id name="id" >
- <generator class="native"/>
- </id>
- <many-to-one name="address"
- column="addressId"
- not-null="true"/>
- </class>
- <class name="Address" >
- <id name="id" column="addressId">
- <generator class="native"/>
- </id>
- </class>
说明:
这是一个多对一的单向关联:由多的一方来维护它们的关系,需要在name="Person"的class元素内加入关联标记,<many-to-one>。这种关联非常多。
假设存在两张表person表和tel表,它们之间的联系是1:n;
即一个人的联系电话可能有多个,一个电话只能对应一个人。
如果在应用的业务逻辑中,我们仅仅关心每个person实例能够查询到其对应的所有tel实例,而tel实例并不需要查询得到其对应的person实例。
- <class name="Person">
- <id name="id" column="personId">
- <generator class="native"/>
- </id>
- <set name="tels">
- <key column="personId" not-null="true" />
- <one-to-many class="Tel"/>
- </set>
- </class>
- <class name="Tel">
- <id name="id" column="telId">
- <generator class="native"/>
- </id>
- </class>
说明:
这是一个一对多的单向关联:由一的一方来维护他们的关系,需要在name="Person"的class元素内加入关联标记,<one-to-many>。这种关联相对要少一些。大部分情况下我们都是操作多的一方的实例。
双向关联
在两边同时配置单向关联,就构成了双向管理。实际开发过程中,很多时候都是需要双向关联的,它在解决单向一对多维护关系的过程中存在的缺陷起了一定的修补作用。
假设存在两张表person表和address表,它们之间的联系是n:1;
即一个人的居住地址是唯一的,一个地址却可以多个人居住。
既需要每个person实例能够查询得到其对应的Address实例,Address实例也需要查询得到其对应的person实例。
- <class name="Person">
- <id name="id" column="personId">
- <generator class="native"/>
- </id>
- <many-to-one name="address"
- column="addressId"
- not-null="true"/>
- </class>
- <class name="Address">
- <id name="id" column="addressId">
- <generator class="native"/>
- </id>
- <set name="people" inverse="true">
- <key column="addressId"/>
- <one-to-many class="Person"/>
- </set>
- </class>
说明:
这是一个多对一双向关联。由双方维护彼此的关系。需要在name="Person"的class元素内加入关联标记,<many-to-one>。同时在name="Address"的class元素内加入集合映射<set>,并在其中加入关联标记:<one-to-many>。
关联标记
在hbm.xml中,关联标记<one-to-one>、<many-to-one>、<one-to-many>、<many-to-many>,关联的方向都是是从左到右。
关联标记属性
简单介绍下面几个,除了name是必须,其余都是可选的。更多的我们参考官文档。
name="对应本类的属性名"
column="映射到本表的字段名"
class="映射到本表的实体类"
unique="ture|false":(数据库外键字段生成一个唯一约束)
not-null="ture|false"默认false(数据库外键字段是否允许为空值)
lazy="ture|false"默认proxy(延迟加载)
关于cascade(级联)属性
级联的意思是指定两个对象之间的操作联动关系,对一个对象执行了操作之后,对其指定的级联对象也需要执行相同的操作
总共可以取值为:all、none、save-update、delete
all-代表在所有的情况下都执行级联操作
none-在所有情况下都不执行级联操作
save-update-在保存和更新的时候执行级联操作
delete-在删除的时候执行级联操作
集合映射标记<set>
- <set name="peoples" inverse="true">
- <key column="addressId"/>
- <one-to-many class="Person"/>
- </set>
<set name="peoples" inverse="true">name为持久化对象的集合的属性名称。
<key column="classid" > column外键的名称
<one-to-many class=“cn.edu.bzu.hibernate.Student" /> class持久化类
关于inverse属性
控制反转,主要用在一对多,多对对双向关联上,inverse可以设置到<set>集合上, 默认inverse为false。为true表示反转,由对方负责;反之,不反转,自己负责;如果不设,one和many两方都要负责控制,因此,会引发重复的sql语句以及重复添加数据。
谁是多谁是一
我们说一对一,多对一,多对多是谁对谁呢?在映射文件(.hbm.xml)中class元素中的对象关联标记中,比如<many-to-one>
那么class元素的属性name就是many,<many-to-one>标记中 name就是one。同时column="addressId"指明了person表的外键。
- <class name="Person" table="person">
- <id name="id" >
- <generator class="native"/>
- </id>
- <many-to-one name="address"
- column="addressId"
- not-null="true"/>
- </class>
上面例子中Person就是many,address就是one。
可以这么理解<many-to-one>在谁里面,谁就是many,<many-to-one>的属性name就是one。
单向关联hbm.xml配置
单向关联常用的是多对一
单向 many-to-one 关联是最常见的单向关联关系。这种关联是数据库关系模式中的多对一:
这个表的一个外键引用目标表的主键字段。
下面例子中的person与address联系(数据库用语)为n:1,可以这么理解:
即一个人的居住地址是唯一的,一个地址却可以多个人居住。
- <class name="Person" table="person">
- <id name="id" >
- <generator class="native"/>
- </id>
- <many-to-one name="address"
- column="addressId"
- not-null="true"/>
- </class>
- <class name="Address" >
- <id name="id" column="addressId">
- <generator class="native"/>
- </id>
- </class>
注意:<many-to-one>标签中column="addressId",为person表添加一个外键addressId。
sql输出:
- create table Person ( personId bigint not null primary key, addressId bigint not null )
- create table Address ( addressId bigint not null primary key )
双向关联hbm.xml配置
1.一对多/多对一
双向多对一关联 是最常见的关联关系。下面的例子解释了这种标准的父/子关联关系。
下面例子中的person与address联系(数据库用语)为n:1,可以这么理解:
即一个人的居住地址是唯一的,一个地址却可以多个人居住。
- <class name="Person">
- <id name="id" column="personId">
- <generator class="native"/>
- </id>
- <many-to-one name="address"
- column="addressId"
- not-null="true"/>
- </class>
- <class name="Address">
- <id name="id" column="addressId">
- <generator class="native"/>
- </id>
- <set name="people" inverse="true">
- <key column="addressId"/>
- <one-to-many class="Person"/>
- </set>
- </class>
注意:many-to-one关联需要将one的一端加入inverse="true";column="addressId"指明了person表的外键。
sql输出:
- create table Person ( personId bigint not null primary key, addressId bigint not null )
- create table Address ( addressId bigint not null primary key )
2.一对一
基于外键关联的双向一对一关联也很常见。
下面例子中person与address的联系(数据库用语)是1:1,可以这么理解:
即一个人只能管理一个地方,一个地方只能由一个人管理。
column="addressId"指明了person表的外键。
- <class name="Person">
- <id name="id" column="personId">
- <generator class="native"/>
- </id>
- <many-to-one name="address"
- column="addressId"
- unique="true"
- not-null="true"/>
- </class>
- <class name="Address">
- <id name="id" column="addressId">
- <generator class="native"/>
- </id>
- <one-to-one name="person"
- property-ref="address"/>
- </class>
sql输出:
- create table Person ( personId bigint not null primary key, addressId bigint not null unique )
- create table Address ( addressId bigint not null primary key )
使用连接表的关联
使用连接表的关联通常针对多对多。连接表会是数据中另外建的一张表,来存储两个实体的联系。
这张表有三个字段:本身的id,两个外键分别关联到两个实体的主键。
下面是student与course的联系(数据库用语)是m:n,可以这么理解:
一个学生可以选多门课程,一门课程也有多个学生。
- <class name="Student">
- <id name="id" column="studentId">
- <generator class="native"/>
- </id>
- <set name="courses" table="StudentCourse">
- <key column="studentId"/>
- <many-to-many column="courseId"
- class="Course"/>
- </set>
- </class>
- <class name="Course">
- <id name="id" column="courseId">
- <generator class="native"/>
- </id>
- <set name="students" inverse="true" table="StudentCourse">
- <key column="courseId"/>
- <many-to-many column="studentId"
- class="Student"/>
- </set>
- </class>
注意:<set>增加了table属性,因此会另外建表。
sql输出:
- create table Student ( studentId bigint not null primary key )
- create table StudentCourse ( studentId bigint not null, courseId bigint not null, primary key
- (studentId, courseId) )
- create table Course ( courseId bigint not null primary key )
hibernate关联关系映射详解的更多相关文章
- hibernate enum映射详解
hibernate enum映射详解 在这里介绍注解的形式,如果想要了解XML配置的方式,可以自行查找相关资料. 例如以下Entity @Entity @Table(name = "t_us ...
- 【ORM】--FluentNHibernate之基本映射详解
最近在做项目的时候用到了NHibernate,使用它并不困难,但是很麻烦.如果我的数据库有几百张表如果想要一个个的映射岂不是很麻烦,所以这种情况下使用NHibernate就会很笨重,虽然 ...
- (转)Hibernate的配置详解
http://blog.csdn.net/yerenyuan_pku/article/details/65041077 在<Hibernate快速入门>一文中,我有讲到Hibernate的 ...
- Hibernate关联关系映射
1. Hibernate关联关系映射 1.1. one to one <class name="Person"> <id name="id" ...
- Hibernate Session & Transaction详解
Hibernate Session & Transaction详解 HIbernate中的Session Session是JAVA应用程序和Hibernate进行交互时使用的主要接口,它也是持 ...
- elasticsearch系列二:索引详解(快速入门、索引管理、映射详解、索引别名)
一.快速入门 1. 查看集群的健康状况 http://localhost:9200/_cat http://localhost:9200/_cat/health?v 说明:v是用来要求在结果中返回表头 ...
- hibernate缓存机制详解
hiberante面试题—hibernate缓存机制详解 这是面试中经常问到的一个问题,可以按照我的思路回答,准你回答得很完美.首先说下Hibernate缓存的作用(即为什么要用缓存机制),然后再 ...
- elasticsearch最全详细使用教程:入门、索引管理、映射详解、索引别名、分词器、文档管理、路由、搜索详解
一.快速入门1. 查看集群的健康状况http://localhost:9200/_cat http://localhost:9200/_cat/health?v 说明:v是用来要求在结果中返回表头 状 ...
- JS数组映射详解
现在这里占个坑位,免的忘了,需要整理一下最近的内容: 1.数组映射的使用 2.微信分享功能详解 3.jq自己封装 4.HTML的富文本应用
随机推荐
- 【C语言】中的布尔类型
C语言中的布尔类型 一.相关基础知识 首先bool true false为C++中的关键字,C语言中默认不支持这几个字符! 二.具体内容 在C89 (ANSI C)标准中没有定义与布尔类型相关的内 ...
- [转]ef获取某个表中的部分字段值
我有个新闻表 id,title,body,createtime,author,click 使用ef4.1 仅仅读取 id,title,createtime 并显示在页面上. public static ...
- ubuntu中vi在编辑状态下方向键不能用的解决
ubuntu中vi在编辑状态下方向键不能用,还有回格键不能删除等,我们平时习惯的一些键都不能使用. 解决办法: 可以安装vim full版本,在full版本下键盘正常,安装好后同样使用vi命令. 安装 ...
- find+*的问题
转自find+*的问题 不久前做移植的时候想把某个目录下的C文件都找出来,然后拷贝下,结果一直报错,我用的是*.c作为pattern.今天看论坛的时候知道为什么了. $ ls test2.c tes ...
- RTSP
相关博客: RTSP 很详细的英文文档 RTSP交互命令简介及过程参数描述 RTSP协议 http://blog.csdn.net/andyweike/article/details/621071 ...
- Windows编程中的堆管理(过于底层,一般不用关心)
摘要: 本文主要对Windows内存管理中的堆管理技术进行讨论,并简要介绍了堆的创建.内存块的分配与再分配.堆的撤销以及new和delete操作符的使用等内容. 关键词: 堆:堆管理 1 引言 在大多 ...
- 在ListView中使用多个布局
要想在一个ListView中使用多个布局文件,比如一个信息List包含了一个信息标题和每个信息对应的时间. 关键的步骤是实现Adapter类的getItemViewType 和getViewTypeC ...
- 'dependencies.dependency.(groupId:artifactId:type:classifier)' must be unique
2016-10-09 23:14:43.177 DEBUG [restartedMain][org.springframework.core.type.classreading.AnnotationA ...
- Handler sendMessage 与 obtainMessage (sendToTarget)
这篇文章讲的很好: http://www.cnblogs.com/android007/archive/2012/05/10/2494766.html 两种用法: 1. private void se ...
- C#面向对象——成员变量及封装
namespace 面向对象5_22 { class Animal { private string _Type; public string Type { get { return _Type; } ...