`

Hibernate读书笔记-----Hibernate的关联映射之1-N关联映射

阅读更多

三、1N

对于1-N而言,它的持久化类发生了一点改变,持久化类里需要使用集合属性。因为1的一端需要访问N的一端,而N的一端将以集合(Set)形式表现。

1、单向1-N关联

对于单向的1-N关联关系,只需要在1的一端增加Set类型的属性,该属性记录当前实体的关联实体。

同样以员工-部门为例(Employee-->Department)。两个持久化类如下:

Department

Employee


1.1基于无连接表的单向1-N关联

对于1-N的单向关联,需要在1的一端增加对应的集合映射元素,如<set.../><bag.../>。在集合元素中需要增加<key.../>子元素,该子元素用来映射外键。同时集合元素中需要使用<one-to-many.../>元素来映射1-N关联关系。

下面是Department的映射文件Department.hbm.xml


对于上面的映射文件,映射<set.../>元素时并没有指定cascade属性,在默认的情况下,对主表实体的持久化操作不会级联到从表实体。

Employee.hbm.xml


使用下面代码来操作DepartmentEmployee实体:保存一个Department实体和两个Employee实体


分析上面代码段:

当程序运行到....1的时候,系统会持久化该对象:Department,而且这个对象已经关联了两个Employee对象。在这个时候Hibernate需要完成两件事:

1、执行insert语句想department表中插入一条记录

2、Hibernate试图执行update语句,将当前的department表记录关联的employee表记录的外键departmentID修改为该department记录的主键的值。

下面为上面代码段的sql语句:

从上面的sql语句中我们可以看到虽然程序仅仅需要为Department实体增加一个关联Employee实体,但是Hibernate会采用两条SQL语句来完成:一条inset语句插入一个条外键为null的employee记录,一条update语句修改插入的employee记录。造成这个问题的根本原因就在于:从Department到Employee的关联并没有被当中为Department对象状态的一部分(程序是通过吧Employee实体添加到Department实体的集合属性中,而Employee实体并不知道她所关联的Department实体),因而Hibernate无法在执行insert语句为该外键指定值。

为了解决这个问题,程序必须在持久化Employee实体之前,让Employee实体能够知道它所关联的Department实体,也就是通过employee.setDepartment(department);方法建立关联关系,但是这个时候就已经变成了1-N的双向关联。所以,尽量少用1-N的单向关联,而改用1-N的双向关联。


1.2基于有连接表的单向1-N关联

对于有连接表的1-N关联映射,映射文件不再使用<one-to-many..../>元素映射关联实体,而是使用<many-to-many.../>元素,但是为了保证当前实体是1的一端,我们需要增加一个属性:unique="true"

所以Department.hbm.xml配置文件如下:

Employee.hbm.xml配置文件保持不变

如果我们依然通过使用操作方法:保存一个Department、两个Employee,这个时候,系统应该是产生5sql语句。其中两条是用于向连接表中插入记录,从而建立DepartmentEmployee之间的关联关系。

2、双向1-N关联

对于1-N关联,Hibernate推荐使用双向关联,而且不要让1端控制关联关系,而使用N的一端控制关联关系。

双向的1-N关联,两端都需要增加对关联属性的访问,N的一端增加引用到关联实体的属性,1的一端增加集合属性,集合元素为关联实体。

两个持久化类和上面差不多,只需要在Employee中增加对Department的引用属性即可。

2.1无连接表的双向1-N关联

对于无连接表的双向1-N关联。N的一端需要增加<many-to-one.../>元素来映射关联属性,而1的一端需要使用<set.../>或者<bag.../>元素来映射关联属性。同时<set.../>或者<bag../>元素需要增加<key.../>子元素映射外键列,并且使用<one-to-many.../>子元素映射关联属性。

在前面已经提到对于1-N关联映射,通常不提倡1的一端控制关联关系,而应该由N的一端来控制关联关系。此时我们可以再<set.../>元素中指定inverse="true",用于指定1的一端不控制关联关系

Department映射文件:Department.hbm.xml


Employee映射文件:Employee.hbm.xml


下面的程序段用于保存一个Department对象和两个Employee对象


SQL语句:


通过上面的SQL语句可以看出,Hibernate并不是采用哪种先insertupdate的方式来插入employee记录的。而是通过一条insertSQL语句来执行的。为什么?因为程序持久化Employee实体之前,Employee已经知道它所关联Department实体(employee2.setDepartment(department);)。所以为了保证比较好的性能,需要注意以下两个问题:

1、应该先持久化主表对象Department。因为我们希望程序在持久化从表:Employee对象时,Hibernate可以为他的外键属性值分配值。

2、先设置两个持久化类(DepartmentEmployee)的关系,再保存持久化从表对象(Employee)。如果顺序反过来,程序持久化Employee对象时,该对象还没有关联实体,所以Hibernate不能为对应记录的外键列指定值,等到设置关联关系时,Hibernate只能再次使用update语句来修改了。

2.2有连接表的双向1-N关联

有连接表的双向1-N关联。1的一端使用集合元素映射,然后在集合元素中增加<many-to-many../>子元素,该子元素映射到关联类。为保证该实体是1的一端,需要增加unique="true"属性。N的一端则使用<join.../>元素来强制使用连接表。

N的一端使用<join../>元素强制使用连接表,因此将使用<key.../>子元素来映射连接表中外键列,器且使用<many-to-one../>来映射连接表中关联实体的外键列;反过来,1的一端也将在<set.../>元素中使用<key.../><many-to-many.../>两个子元素,他们也映射到连接表的两列。为了保证得到正确的映射关系,应该满足如下关系:<join.../><key.../>子元素的column属性和<set.../><man-to-many.../>元素的column属性相同;<join.../><many-to-many.../>子元素的column属性和<set../>元素的<key../>子元素的column属性应该相等。

下面就是DepartmentEmployee两个持久化类的映射文件:

Department.hbm.xml

Employee.hbm.xml


读李刚《轻量级JavaEE 企业应用实战》

分享到:
评论

相关推荐

    Hibernate映射笔记

    hibernate配置关系的笔记

    J2EE三大框架_笔记_a

    J2EE三大框架_笔记 共分三块: J2EE框架_笔记_a: 1-JSP+JDBC_假分页笔记 2-JSP+JDBC_真分页(基于Oracle数据库分页)笔记 3-JSP+DAO和MVC+DAO(基于MySQL数据库分页...54留言管理程序_Struts + Spring + Hibernate笔记

    J2EE框架_笔记_c

    J2EE三大框架_笔记 共分三块: J2EE框架_笔记_a: 1-JSP+JDBC_假分页笔记 2-JSP+JDBC_真分页(基于Oracle数据库分页)笔记 3-JSP+DAO和MVC+DAO(基于MySQL数据库分页...54留言管理程序_Struts + Spring + Hibernate笔记

    hibernate学习笔记

    Hibernate 学习笔记 1 第一个hibernate项目(hibernate_first) 2 测试实体对象的生命周期(hibernate_session) 3 hibernate基本映射(hibernate_basemapping) 4 class实体类---表 4 标签id 5 主键生成器Generator 6...

    J2EE框架_笔记_b

    J2EE三大框架_笔记 共分三块: J2EE框架_笔记_a: 1-JSP+JDBC_假分页笔记 2-JSP+JDBC_真分页(基于Oracle数据库分页)笔记 3-JSP+DAO和MVC+DAO(基于MySQL数据库分页...54留言管理程序_Struts + Spring + Hibernate笔记

    Hibernate_容器映射技术笔记

    Hibernate_容器映射技术笔记Hibernate_容器映射技术笔记Hibernate_容器映射技术笔记Hibernate_容器映射技术笔记

    JPA学习笔记-EJB-04JPA关联映射总结

    感觉JPA关联映射实现感觉比Hibernate配置文件的关联映射几乎一样,只是引入了“零配置”这个概念。劣者自己在做一个东西的时候用到了关联映射,在此将它做一个总结。留给自己回顾用。

    Hibernate学习笔记

    001 Hibernate 简介(开源 O/R 映射框架) 002 第一个 Hibernate 示例 003 hibernate 主要接口介绍 004 持久对象的生命周期介绍 005 query 接口初步 006 开源 O/R 映射框架内容回顾 007 Hibernate 基本映射标签和属性...

    javaEE框架笔记,识货人下

    54留言管理程序_Struts + Spring + Hibernate笔记.pdf 6-Struts标签-BEAN标签笔记.pdf 7-Struts标签 -LOGIC标签笔记.pdf 8-Struts标签- HTML标签笔记.pdf 9-Struts高级部分(1)(解决重复提交、上传组件)笔记.pdf

    hibernate笔记

    1 下载hibernate-distribution-3.3.2.GA-dist 5 2 下载hibernate-annotations-3[1].4.0.GA 5 3 注意阅读hibernate compatibility matrix(hibernate 网站download) 5 4 下载slf4jl.5.8 6 Hibernate HelloWorld 6 1 ...

    Hibernate中单一映射笔记

    Hibernate开发过程(单一映射体) 1创建持久类XXXX.java(要有oid字段:唯一且不具有业务含义;所有属性都有getter/setter方法;空的构造方法;不含oid的构造方法) 2创建映射文件XXXX.hbm.xml(包,类,id,字段) 3...

    Hibernate学习笔记和资料

    hibernate概述,hibernate入门Demo,hibernate配置文件详解(全局配置,实体类映射配置),配置实体规则,核心API详解(Configuration,sessionFactory,session,Transaction),hibernate中的对象状态以及刷新能缓存机制 ...

    hibernate初学者笔记

    关于hibernate的Session,向数据插入时的事务隔离级别,持久化对象的状态,对应关系的映射文件,表与表之间的多种映射关系,以及hibernate的二级缓存的笔记。

    Hibernate笔记 马士兵

    第9课 Hibernate的重点学习:Hibernate的对象关系映射 12 一、对象---关系映射模式 12 二、常用的O/R映射框架: 13 第10课 模拟Hibernate原理(OR模拟) 13 一、 项目名称 13 二、 原代码 13 第11课 Hibernate基础配置...

    Spring和Hibernate学习笔记

    第四课:hibernate多对一关联映射 ...................... Spring: 第一课:构建Spring的环境并建立一个例子 第三课:spring Bean的作用域 第四课:spring对AOP的只是(采用Annotation的方式) 第五课:spring对AOP...

    Hibernate学习笔记_songjignhao_1

    自己记录的学习笔记,内容很详细,有代码,包括:一对多双向关联关系、一对多双向自身关联关系、一对一关联关系(主键关联、外键关联)、一对多与一对一结合、多对多关联关系、Map、Set、List与Bag映射关系、查询...

    Hibernate - 学习笔记

    使用Hibernate对数据进行操作时会牵涉到3种类型的文件:Java类(实体类),映射文件(test.hbm.xml),数据库的表结构(表结构的创建).从理论上说只要知道其中一个,另外两个就可以从知道的那个文件中生成出来,这就涉及到先...

    Hibernate3 学习笔记.ppt

    Hibernate3 学习笔记.ppt ...三、Hibernate映射申明(Mapping declaration) 四、Hibernate Annotations 五、持久化对象的状态和生命周期 六、Hibernate查询 七、Hibernate最佳实践 八、Hibernate Tool

    Hibernate实体映射

    里面包含Hibernate实体映射的具体实例代码,还有相关教程笔记,喜欢的可以学习学习。

    Hibernate_映射配置文件详解.ppt

    Hibernate_映射配置文件详解,很好用的学习文件

Global site tag (gtag.js) - Google Analytics