Hibernate之关系映射

Hibernate之关系映射

在关系型数据库存在着4种关系映射:多对一、一对多、一对一、多对多,下面依次对这四种关系如何在关系模型和对象模型中实现加以说明。

【多对一】

比如有Employee类和Department类,其中employee相对于department来说就是多对一,因为多个employee可以属于同一个department.

在关系模型中要实现这种映射需要在t_employee表中加一列departmentId,外键约束为t_department的主键id上。

而在对象模型中,只需要让Employee类中有一个department的属性.

要想在hibernate中映射这种关系,需要在多的一方,这里就是Employeed.hbm.xml中使用<many-to-one>标签。

<many-to-one name="department"  column="departmentId" class="Department"  cascade="all" outer-join="true"/>


其中column属性指定用t_emplyee表中的哪一列去匹配t_department表的主键

  class属性指定用什么类去映射t_department表

  cascade属性表示当employee对象save,update 或者 delete的时候,是否需要对department进行相应的操作

  outer-join属性:当查询t_employee表时,hibernate默认是先查询出employee的departmentId,然后根据这个departmentId去t_department中查询对应的department,但当outer-join设置为true时,hibernate会采用表连接的方式同时将两张表中的数据查询出来。

【一对多】

还是上面的employee和department的例子,department相对于employee就是一对多的关系,因为一个department可以有多个employee.

这种关系在关系模型下的实现和多对一是一样的,还是在【多】的一方建立一个外键,关联到【一】的主键上。

但对象模型需要修改下,需要在【一】的属性中加一个集合属性,用来存放与之对应的【多】对象,在这个例子就是要在Department类中加一个List<Employee> employees.

而Hibernate中要想实现这种映射,需要在Department.hbm.xml中使用<set>标签

<set name="employees" table="t_employee" cascade="all">
            <key column="departmentId"/>
            <one-to-many class="Department"/>
</set>

无论是设置<many-to-one>的column属性还是<set>标签的子元素标签<key>,只要记住,hibernate需要知道用【多】这一方的哪一列去和【一】的主键匹配,所以要提供外键的列明。

【双向映射】

上面讲的无论是多对一还是一对多都是单向的,只能通过employee找到department,或者只能通过department找到employee,要想实现双向的也很简单,只要同时在【多】的一方使用<many-to-one>,还要在【一】的一方使用<set>就行了,但这里有个问题要注意,在使用双向映射的时候,要把关系维持的控制权给多的一方,不然hibernate会发insert语句,然后发update语句,可以形象的比喻,是公司的老板记住所有员工的名字快,还是让所有员工记住老板的名字快?如何把控制权给【多】的一方呢,就是在一的一方的<set/>设置inverse属性为true.

【一对一】

employee和idCard就是这种关系,一个employee只可能有一个idCard,一个idCard也只可能对应一个employee,其中employee叫主对象,idCard叫从对象,因为没有了employee,idCard是没有意义的。

在关系模型中有两种方法实现这种关系,但在对象模型中,只要互相持有对方的引用即可,下面分别将如何在关系模型中实现这种关系,以及hibernate如何映射。

一、主键关联

即让从对象的主键和主对象的主键一样。

在主对象employee.hbm.xml中使用<one-to-one>标签

<one-to-one name="idCard"  class="IdCard" cascade="all"/>

不用指定column属性,因为hibernate知道用两张表的主键去匹配

在从对象idCard.hbm.xmlo中同样也要使用<one-to-one>标签

<one-to-one name="employee"  class="Employee" constrained="true"/>

因为idCard的主键是根据employee的主键而来的,所以特别配置主键的生成策略

<id name="id" column="id">
            <generator class="foreign">
            <param name="property">user</param>
            </generator>
</id>

在IdCard的id主鍵上,使用foreign表示與外鍵共享主鍵,也就是與Employee實體共享主鍵,而constrained設定為true,表示約束
idCard的主鍵必須與employee中對應資料的主鍵相同。

二、唯一外键关联

这种方式关系模型实际就是多对一,但加了一个约束,要求外键不能重复

加入unique="true"即可完成单向的一对一:

<many-to-one name="department"
                     column="departmentId"
                     class="Department"
                     cascade="all"
                     outer-join="true"
                     unique="true"/>

如果想要实现双向的一对一,需要在department.hbm.xml也加入<one-to-one>

<one-to-one name="employee"
                   class="onlyfun.caterpillar.User"
                   property-ref="deparment"/>

猜你喜欢

转载自zhang-long-zl.iteye.com/blog/1990159