Hiberbate关系映射

作为一种轻量级的关系映射工具,Hibernate支持各种关系映射,例如:多对一、一对多和一对一的数据库表关系,通过映射文件的灵活配置即可轻松实现。Hibernate的重要部分就是关系映射。本章我们将会就这几个关系进行说明介绍:

  • 单向多对多映射
  • 双向多对多映射
  • 单向多对一映射
  • 单向一对多映射
  • 双向一对多(多对一)映射
  • 基于外键的单向一对一映射
  • 基于外键的双向一对一映射
  • 基于主键的单向一对一映射
  • 基于主键的双向一对一映射
    这里,在介绍的过程中,会着重介绍配置文件的核心代码变化,而忽略掉Test测试方法。另外,需要注意的是基于外键、主键以及无任何的关系与变化。

1.1 单向多对多映射

这里我们使用实例来进行说明:
假设有角色和用户组两个表,是多对多的关系,即一个角色可以多个用户组拥有,一个用户组也可以拥有多个角色。这里我们在进行编写的时候呢,就需要增加一个角色-组的对应表,用来记录多对多的关系。
例如一个网站的用户角色可以有查看、添加、删除和修改等功能,用户又可以分为管理员、版主、注册用户和匿名用户等,那么这里的用户和角色就是多对多的关系,即一个用户可以拥有多个角色,每个角色也可以赋给多个用户。
步骤:
1.建立角色表、用户表以及角色-用户表。第三个表主要就是将他们在各自关系表中的主键属性进行创建一个表。
2.建立角色实体类。这里我们需要注意的是将用户表也进行实例化,也就是在创建的时候,需要建立一个集合类型属性变量,这样才能展现出多个用户。

private Set groups = new HashSet();

3.建立用户组的实体类
这里与上面的是一致的,也需要将角色表进行实例化。

private Set roles = new HashSet();

4.因为角色端是多对多的控制方,其映射文件可以进行编写:

<!-- 配置多对多关系映射 -->
<set name="groups" cascade="save-update">
    <key column="role_id"></key>
    <many-to-many class="*" column="group_id"></many-to-many>
</set>

5.Group(用户组)是被控制方,在进行编写的时候,我们不需要进行特别的主要,就像原来的那么编写即可。
6.编写测试类Test
这里笔者就不一一说明测试类的书写了,这里我们只需要注意Set集合的编写方法。

1.2 双向多对多映射

我们还是使用上面的例子进行说明。
首先,根据上面的步骤,我们需要修改角色端映射文件的代码书写。
这里我们需要在Set标签中再加入一个属性——inverse。
inverse属性负责控制关系,默认为false,也就是关系的两端都能控制,但这样会造成一些问题。更新时会因为两端都控制关系,于是重复更新。一般来说有一端要设为true,也就是让另一端进行控制关系。
第二,我们需要在用户组映射文件中进行编写。

<!-- 配置多对多关系映射 -->
<set name="roles" cascade="save-update">
    <key column="group_id"></key>
    <many-to-many class="*" column="role_id"></many-to-many>
</set>

这样,我们就比较好的将双向与单向多对多的映射进行了比较与介绍。

1.3 单向多对一映射

在数据库表关系中,经常出现多对一的映射,例如一个人只能有一个住址(假定),一个住址可以住多个人。那么人和住址就是多对一的关系。
步骤:
1.建表,人(Person)、住址(address)。
2.建实体类,这里只需要在多的那一端也就是人实体类建立一个住址属性变量。

private Address address;

而另外一端,则如同正常的实体类一般进行编写即可。
3.建立Person.hbm.xml映射文件:

<!-- 配置多对一的关联关系 -->
<many-to-one name="address" column="address_id"></many-to-one>

就能达到控制单向多对一关系映射。
4建立Address.hbm.xml映射文件
不需要进行特别的配置,略过。。。
5.添加测试类Test

1.4单向一对多映射

比较典型的一对多映射就是公司与雇员的关系,即一个公司可以有多个雇员。
单向一对多的映射关系并不是很常见,其配置同单向多对一非常相似,其主动方为“一”的一方,使用one-to-many配置属性。
步骤:
1.建表。公司表(company)、雇员表(employee)。
2.建公司与雇员的实体类。略。PS:我想有点读者已经发现了,多与一的时候,我们只需要在一的那边编写类的属性变量。
3.编写公司映射文件Company.hbm.xml。

<!-- 配置一对多关系映射 -->
<set name="employees" cascade="all">
       <key column="com_id"></key>
       <one-to-many class="*"></many-to-many>
</set>

4.雇员映射文件Employee.hbm.xml
略过,与一般相同。
5.编写测试类Test

1.5 双向一对多(多对一)映射

常见的双向一对多或者是多对一映射是父子关系
步骤:
1.建立数据库表。father、son
2.建立实体类
3.映射文件Father.hbm.xml的配置

<!-- 配置一对多关系映射 -->
<set name="sons" cascade="all" incerse="true">
     <key column="father_id"></key>
     <one-to-many class="*"></many-to-many>
</set>

4.映射文件Son.hbm.xml配置

<!-- 配置多对一的关联关系 -->
<many-to-one name="father" column="father_id"></many-to-one>

5.编写测试类Test

1.6 基于外键的单向一对一映射

基于外键的单向一对一映射,常见的例子是用户(user)和电子邮件(email),每个用户只有一个电子邮件,并通过外键email_id同电子邮件相对应。但是电子邮件没有对应的用户
步骤:
1.建立email、user数据库表
2.建立实体类。
在User.java中,我们需要定义一个邮件类型变量

private Email email;

3.映射文件User.hbm.xml

<!-- 配置多对一的关联关系 -->
<many-to-one name="email" column="email_id" class="*" unique="true">
</many-to-one>

在这个映射文件中,我们给many-to-one配置了一个unique属性。
配置这个属性的作用是不能有重复的主键,就限定了"多"的一方必须变成“一”,这样就实现了一对一映射。单向的一对一映射,只需要配置一方即可。
4.映射文件Email.hbm.xml
与一般相同即可。
5.编写测试类Test

1.7基于外键的双向一对一映射

修改前一节单项映射为双向映射。在保持数据库表不变的情况下,增加相应的配置信息,实现双向映射。例如:用户表与电子邮件就是双向一对一的映射关系,即每个用户都有唯一的电子邮件对应,例如常见的电子商务网站淘宝和ebay等,一对一可以通过主键对应,也可以通过外键来对应。

  • one-to-one
  • property-ref
    步骤:
    1.数据库表结构与上节一样
    2.双向所以两个实体类都要进行编写类属性变量
    3.映射文件User.hbm.xml
<!-- 配置一对一的关联关系 -->
<many-to-one name="email" column="email_id" unique="true">
</many-to-one>

4.映射文件Email.hbm.xml

<!-- 配置一对一的关联关系 -->
<one-to-one name="user" property-ref="email">
</one-to-one>

property-ref属性:指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键
5.编写测试类Test

1.8 基于主键的单向一对一映射

一对一映射,前面介绍的是基于外键的,还有一种基于主键的一对一映射,即两个表的主键值相同。单向一对一的情况不多,例如用户和电子邮件之间的关系,假定没有用户必须有唯一的电子邮件与之对应,而电子邮件可以没有对应的用户,即对应关系是单向的。
基于主键的一对一映射特点是两个表都以主键作为关联字段,这同基于外键的一对一映射有很大的不同,即关联字段都是各自的主键。
步骤:
1.建表。同时都以ID作为主键。
2.建立实体类。这里和基于外键的不同是单向两个实体类同时都要建立类属性变量。
3.Emailpk.hbm.xml映射文件
这里呢?有一个比较重要的属性。

<id ... >
        <column .../>
        <generator class="foreign">
                   <param name-"property">userpk</paprm>
        <generator>
</id>
...
<one-to-one name="userpk" class="*" constrained="true">
</one-to-one>

这里,我们引进了几个其他的属性。
generator class="foreign" 意味着Emailpk使用外部主键,<param name="property">userpk</param>配置了Emailpk使用Usepk的主键作为自己的主键,这样就实现了基于主键的一对一映射。
constrained="true"说明userpk的主键值存在一个约束,即emailpk使用了userpk的主键。
4.Userpk.hbm.xml映射文件
与一般相同,不做阐述。
5.编写测试文件Test

1.9基于主键的双向一对一映射

前面介绍了基于主键的单向一对一映射,本节介绍基于主键的双向一对一映射,还是使用前面的数据库表和相关类。例如用户和电子邮件之间的关系,每个用户有唯一的电子邮件,每个电子邮件有唯一的用户,假如这种对应是通过各自的主键实现的,那么就是基于主键的双向一对一映射关系。
步骤:
1.建表。
2.编写实体类。
3.映射文件Emailpk.hbm.xml
与上面的一样。
4.映射文件Userpk.hbm.xml

<one-to-one name="emailpk" class="*" constrained="true">
</one-to-one>

5.编写测试类Test。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容