Java EE入门教程系列第六章Hibernate框架(二)——Hibernate对象关系映射

7.2 Hibernate对象关系映射

7.2.1 对象关系映射的基本概念

ORM是Hibernate实现的核心思想。ORM的实现思想就是将对象映射为关系数据库中的表,或者反过来。Hibernate正是采用了这种思想,方便了开发人员以面向对象的思想来实现对数据库的操作。

ORM是数据库表和对象之间的映射关系。在建立数据库的表时,一般首先对数据库进行建模,画出E-R图,然后再根据实体联系模型也就是E-R图来建立关系模型,再建立相应的表。实体间一般存在3种联系:一对一、一对多和多对多。在Hibernate的ORM中,类与表之间的映射,主要是通过映射文件来确定类与表之间的对应关系,同时类与类之间的关系也会影响与表的映射关系。在学习面向对象设计时已知,类与类之间存在5种关系:继承、实现、关联、依赖和聚合/组合,Hibernate中的POJO类之间的关系也是如此。

Hibernate中的ORM映射文件通常以.hbm.xml作为扩展名,使用这个文件不仅易读,而且可以手工修改,也可以通过一些工具来生成映射文档。

6.2.2 基本类映射过程

Hibernate在实现ORM功能时主要用到的文件有:

1)映射类(*.java):映射类一般是POJO类,对应描述关系数据库的表的结构,类中的属性往往被描述成表中的字段,可以实现把表中的记录与该类的对象进行相互映射。

2)映射文件(*.hbm.xml):指定数据库表和映射类之间的关系,包括映射类和数据库表的对应关系、表字段和类属性类型的对应关系,以及表字段和类属性名称的对应关系等。

3)数据库配置文件(*.properties/*.cfg.xml):指定与数据库连接时需要的连接信息,如连接哪种数据库、登录数据库的用户名、登录密码及连接字符串等。当然还可以把地址映射信息放在这里。

6.2.3 关系映射类型

(1)“单向一对一”关联映射(one-to-one)

两个对象之间是一对一的关系,如人-身份证,单向一对一主键关联,靠的是他们的主键相等。在映射文件中,通过one-to-one元素定义:

                                            (图片来自网络,不妥侵删)

<class name="com.test.Person" table="t_table">
<id name="id">
<!--采用foreign生成策略,foreign会取得关联对象的标识-->
<generator class="foreign">
<!--property是关联对象-->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!--一对一关联映射,主键关联-->
<!--one to one标签指示hibernate如何加载其关联对象,默认根据主键加载。也就是拿到关键字段值,根据对端的主键来加载关联对象。constrained="true"表示当前主键还是一个外键。参照了对端(IdCard)的主键,也就是会生成外键约束语句-->
<one-to-one name="idCard" constrained="true"/>
</class>

(2)“单向多对一”关联映射(many-to-one)

原理为:在“多”的一端加入一个外键,指向“一”的一端,比如下面左图,可以在多的一端加入以下标签映射:

<many-to-one name="group"  column="groupid"/>

(3)“单向一对多”关系映射(one-to-many)

与多对一原理一致,如下面右图。注意他与多对一的区别是维护的关系不同。多对一维护的关系是:多指向一的关系,加载多的时候 可以把一加载上来;一对多则相反。可以在映射文件的“一”端加入以下标签映射:

<set name="students">

<key column="classesid"/>

<one-to-many class="con.Student"/>

</set>

(4)“单向多对多”关联映射(many-to-many)

此时一般要新增一张表才能完成基本映射比如实体“用户”和“角色”之间就是多对多关联,要描述这种关系,要新增一张表(t-user-role)来完成映射:

在进行映射处理时,可以在映射文件的user一端加入以下标签:

<set name="roles" table="t-user-role">

<key column="user-id"/>

<many-to-many class="com.Role" column="role-id"/>

</set>

(5)“双向一对一”

对比单向一对一,人和身份证的双向一对一需要在IdCard中加入<one-to-one>标签,它只影响加载

双向一对一主键映射,可以在映射文件的IdCard端新加入以下标签:

<one-to-one name="person"/>

双向一对一唯一外键映射,可以在映射文件的IdCard端新加入以下标签:

<one-to-one name="person" property-ref="idCard"/>

注意:双向一对一唯一外键映射采用one-to-one标签映射,必须指定其中的property-ref属性为关系字段的名称。

(6)“双向一对多”

采用双向一对多主要是解决单向一对多关联的缺陷,而不是由需求所驱动的。

双向一对多关联的映射关系如下:

在“一”的一端的集合上采用<key>标签,在多的一端加入一个外键

在多的一端采用<many-to-many>标签

注意:这两个标签加入的字段应保持一致,否则会产生数据混乱。映射文件中的关键映射代码,可以在classes的“一”端加入以下标签:

<set name="students" inverse="true">

<key column="classesid"/>

<one-to-many class="con.Student"/>

</set>

在student的“一”端加入:

<many-to-one name="classes" column="classesid"/>

其中,inverse属性可以用在双向一对多和双向多对多关系上,默认值为false,表示本端可以维护关系;如果值为true,会交给另一端维护关系,本端失效。所以双向一对多通常在多的一端维护关系,该属性是控制方向上的反转,只影响存储。

(7)role端关键映射代码为:

<set name="roles" table="t-user-role">

<key column="user-id"/>

<many-to-many class="com.User" column="role-id"/>

</set>

user端关键映射代码为:

<set name="roles" table="t-user-role">

<key column="user-id"/>

<many-to-many class="com.Role" column="role-id"/>

</set>

综上所述,可以看出,同一类映射,无论是单向还是双向,它们的存储结构都是相同的,之所以映射文件不同,是因为加载不同。无论是一对一、一对多还是多对一、多对多,A对B,A就是主动方,A主动想了解B的情况,这样把B设置到A端。而双向也就是双方同样都想了解对方的情况,那就要同时也把A端设置到B端了。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值