为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

第13章 复杂映射关系

2011-06-29 28页 ppt 196KB 41阅读

用户头像

is_928365

暂无简介

举报
第13章 复杂映射关系null第13章 复杂映射关系第13章 复杂映射关系本章将介绍几种复杂的映射关系:关联关系映射、集合类的映射、组件映射和继承关系映射。与前一章基础映射都是针对单个类不同,这些映射都是涉及两个或者两个以上的类,除了映射类本身与数据库表之间的关系外,还要在映射文件中表达类与类之间的关系。 源码网:www.codepub.com13.1 关联关系映射13.1 关联关系映射Hibernate中的关联(Association)映射主要有3种:一对一关联、一对多(或多对一)关联、多对多关联。每种关联都可以分为单向和双向两种。关...
第13章  复杂映射关系
null第13章 复杂映射关系第13章 复杂映射关系本章将介绍几种复杂的映射关系:关联关系映射、集合类的映射、组件映射和继承关系映射。与前一章基础映射都是针对单个类不同,这些映射都是涉及两个或者两个以上的类,除了映射类本身与数据库之间的关系外,还要在映射文件中表达类与类之间的关系。 源码网:www.codepub.com13.1 关联关系映射13.1 关联关系映射Hibernate中的关联(Association)映射主要有3种:一对一关联、一对多(或多对一)关联、多对多关联。每种关联都可以分为单向和双向两种。关联关系映射通常情况是最难配置正确的。在这个部分中,本节将从单向关系映射开始,然后考虑双向关系映射,最后介绍一个完整的实例。13.1.1 多对一(many to one)13.1.1 多对一(many to one)单向many-to-one关联是最常见的单向关联关系。如图所示,类与类之间是多对一的关系。13.1.2 一对一(one to one)13.1.2 一对一(one to one)一对一的关联分为外键关联和主键关联。 (1)外键关联:基于外键关联的单向一对一关联和单向多对一关联几乎是一样的。唯一的不同就是单向一对一关联中的外键字段具有唯一性约束。 (2)主键关联:基于主键关联的单向一对一关联通常使用一个特定的id生成器。这里的关联关系是定义在Address类的映射文件中,在辅表的one-to-one的属性里要加constrained="true"表示受到约束。13.1.3 一对多(one to many)13.1.3 一对多(one to many)基于外键关联的单向一对多关联是一种很少见的情况,并不推荐使用。此时的Person包含一个addresses字段,这个字段是一个Address类的集合。 public class Person { //一对多实现,包含一个集合类属性 private Set addresses= new HashSet(); public Set getAddresses () { return addresses; } public void setAddresses (Set addresses) { this. addresses= addresses; } }13.1.4 双向关联(Bidirectional associations)13.1.4 双向关联(Bidirectional associations)以上介绍的都是把关联关系定义在两个类中的一个类,也就是主控类中。只有对主控类操作的时候,才会涉及到关联关系,这样还不足以严格表达明确的关联关系。很多时候还需要表达双向的关联关系,也就是在两端的映射中都定义关联关系。 inverse映射属性究竟表示什么呢?一个双向关联仅仅是在两端简单地正确设置引用。然而,Hibernate并没有足够的信息去正确地执行INSERT和UPDATE语句(以避免违反数据库约束),所以它需要一些帮助来正确的处理双向关联。把关联的一端设置为inverse将告诉Hibernate忽略关联的这一端,把这端看成是另外一端的一个镜象(mirror)。这就是所需的全部信息,Hibernate利用这些信息来处理把一个有向导航模型转移到数据库schema时的所有问题。13.1.5 双向一对一13.1.5 双向一对一双向一对一与单向类似也是分为两种。 (1)基于外键关联的双向一对一关联也很常见。 (2)基于主键关联的一对一关联需要使用特定的id生成器。13.1.6 使用连接表(with join tables)13.1.6 使用连接表(with join tables)如果想保持关联两个表的独立性,也就是不想在Person表中出现类似addressId这样不容易理解的字段,就需要使用连接表。专门定义一张表来维护Person与Address之间的关系。关联表结构如图所示。13.1.7 多对多(many to many)13.1.7 多对多(many to many)对于多对多关联或叫n:m实体关系(类图如图13.3所示),需要一个关联表(association table)。表里面的每一行代表从person到address的一个关联。表名是由set元素的table属性配置的。关联里面的标识符字段名,对于person的一端,是由元素定义,而address一端的字段名是由元素的column属性定义。也必须告诉Hibernate集合中对象的类(也就是位于这个集合所代表的关联另外一端的类)。 (1)单向多对多关联。 (2)双向多对多关联13.1.8 完整实例13.1.8 完整实例本节将展示一个完整的一对多/多对一双向的实例。 (1)持久化类。为了与之前的示例区分,这里使用时User类和Room类, (2)映射文件。 (3)测试代码如代码所示,给room增加两个user后直接保存room对象。 (4)运行结果。 (5)指定inverse。13.2 集合类(Collections)映射13.2 集合类(Collections)映射Java提供了丰富的集合类库,它们可分为3类: Set:集合中的对象不按特定方式排序,而且没有重复对象。(有些Set也提供了排序功能如TresSet,不过这并不是Set接口的特性) List:集合中的对象按索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象。 Map:集合中的每一个元素包含一对键对象和值对象,集合中没有重复的键对象,值对象可以重复。(有些Map也提供了排序的能力如TreeMap) Hibernate允许把以上3种Java集合都映射到数据库中。在映射文件中,与映射java结合相关的元素包括。13.2.1 持久类中的集合类13.2.1 持久类中的集合类Hibernate要求持久化集合值字段必须声明为接口,比如java.util.Set、java.util.Collection、java.util.List、java.util.Map。而不能直接定义为ArrayList、HashMap这些具体的集合类。 集合几乎可以包含任何其他的Hibernate类型,包括所有的基本类型、自定义类型、组件,当然还有对其他实体的引用。存在一个重要的区别:位于集合中的对象可能是根据“值”语义来操作(其声明周期完全依赖于集合持有者),或者它可能是指向另一个实体的引用,具有其自己的生命周期。在后者的情况下,被作为集合持有的状态考虑的,只有两个对象之间的“连接”。13.2.2 映射集合13.2.2 映射集合用于映射集合类的Hibernate映射元素取决于接口的类型。重要的属性含义如: name集合属性的名称。 table(可选——默认为属性的名称)这个集合表的名称(不能在一对多的关联关系中使用)。 schema (可选) 表的schema的名称, 他将覆盖在根元素中定义的schema。 lazy (可选--默认为true) 可以用来关闭延迟加载(false),指定一直使用预先抓取,或者打开"extra-lazy" 抓取,此时大多数操作不会初始化集合类(适用于非常大的集合)。 inverse (可选——默认为false) 标记这个集合作为双向关联关系中的方向一端。 cascade (可选——默认为none) 让操作级联到子实体。 sort(可选)指定集合的排序顺序, 其可以为自然的(natural)或者给定一个用来比较的类。13.2.2 映射集合13.2.2 映射集合order-by (可选,仅用于jdk1.4)指定表的字段(一个或几个)再加上asc或者desc(可选),定义Map,Set和Bag的迭代顺序。 where (可选) 指定任意的SQL where条件,该条件将在重新载入或者删除这个集合时使用(当集合中的数据仅仅是所有可用数据的一个子集时这个条件非常有用)。 fetch (可选,默认为select)用于在外连接抓取、通过后续select抓取和通过后续subselect抓取之间选择。 batch-size (可选,默认为1)指定通过延迟加载取得集合实例的批处理块大小("batch size")。 access(可选-默认为属性property):Hibernate取得集合属性值时使用的策略。 optimistic-lock乐观锁(可选 - 默认为true):对集合的状态的改变会是否导致其所属的实体的版本增长。(对一对多关联来说,关闭这个属性常常是有理的)。 mutable(可选 - 默认为true):若值为false,表明集合中的元素不会改变(在某些情况下可以进行一些小的性能优化)。13.2.3 映射外键13.2.3 映射外键集合实例在数据库中依靠持有集合的实体的外键加以辨别。此外键作为集合关键字段(collection key column)(或多个字段)加以引用。集合关键字段通过 元素映射。 在外键字段上可能具有非空约束。对于大多数集合来说,这是隐含的。对单向一对多关联来说,外键字段默认是可以为空的,因此可能需要指明 not-null="true"。 外键约束可以使用ON DELETE CASCADE。 13.2.4 映射索引13.2.4 映射索引所有的集合映射,除了标记的以外,都需要指定一个集合表的索引字段(index column)——用于对应到数组索引,或者List的索引,或者Map的关键字,被映射的字段包含有顺序排列的整数(默认从0开始)。有以下几种标记来映射索引 (1)通过映射的索引可以是任何基础类型; (2)通过,它也可以是一个实体引用; (3)通过,它还可以是一个组合类型。数组或列表的索引必须是integer类型,并且使用元素定义映射。13.2.5 集合类排序13.2.5 集合类排序在Hibernate中,对集合类排序有3种方式可以选择。 (1)利用比较器排序。Hibernate支持实现java.util.SortedMap和java.util.SortedSet的集合。必须在映射文件中指定一个比较器,sort属性中允许的值包括unsorted,natural和某个实现了java.util.Comparator的类的名称。分类集合的行为事实上象java.util.TreeSet或者java.util.TreeMap。 (2)可以利用set,bag或者map映射中的order-by属性,这样的做法实际上是调用数据库的order by命令来排序,把排序的工作交给数据库去做。 (3)关联还可以在运行时使用集合filter()根据任意的条件来排序。 sortedUsers = s.createFilter( group.getUsers(), "order by this.name" ).list();13.2.6 完整的Map实例13.2.6 完整的Map实例实例是关于上档案(files)管理。每一个使用者可以上载自己的档案,并为档案加上描述,可以使用Map型态物件来记录上传的档案,以档案描述作为键(key),以档案名称作为值(value),13.3 组件映射13.3 组件映射组件(Component)这个概念在Hibernate中几处不同的地方为了不同的目的被重复使用。13.3.1 依赖对象13.3.1 依赖对象这里的组件(Component)是一个被包含的对象,在持久化的过程中,它被当作值类型,而并非一个实体的引用。组件这一术语指的是面向对象的合成概念(而并不是系统构架层次上的组件的概念)。依赖关系类图如图所示。13.3.2 在集合中出现的依赖对象13.3.2 在集合中出现的依赖对象Hibernate支持组件的集合(例如:一个元素是Name这种类型的数组)。可以使用标签替代标签来定义组件集合。 ; 13.3.3 组件作为联合标识符13.3.3 组件作为联合标识符使用标签(并且内嵌元素)代替通常的标签可使组件作为联合标识符。比如,OrderLine类具有一个主键,这个主键依赖于Order的(联合)主键, (1)一个指向OrderLine的关联可能被这样映射 (2)指向OrderLine的多对多关联也使用联合外键 (3)在Order中,OrderLine的集合则是这样 (4)假若OrderLine本身拥有一个集合,它也具有组合外键 13.3.4 动态组件13.3.4 动态组件组件的构成可以用Map来代替一个类,由Map的key来代替类的属性,如: 13.4 继承关系映射13.4 继承关系映射对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念。Hibernate的继承映射可以同样理解为两个持久化类之间的继承关系,例如客户(Customer)、经理(Manager)、雇员(Employee)和人(Person)之间的关系,雇员继承了人,可以认为雇员是一个特殊的人,那么如果对人进行查询,人在子类雇员实例也将被得到而无须关注人的实例、雇员的实例底层数据库的存储。13.4.1 采用所有的类同在一张表13.4.1 采用所有的类同在一张表在这种映射策略下,整个继承树的所有实例都将保存在同一个张数据表中,即以上的Person、Employee、Customer和Manager实例都将保存在同一个表内。因为将父类和子类的实例全部保存在同一个表内,因此,需要在该表内额外增加一列,使用该列来区分每行记录到底是哪个类的实例——这个列被称为辨别者列(discriminator)。13.4.2 采用每个子类一张表13.4.2 采用每个子类一张表采用每个子类一张表需要使用标记,父类实例保存在父类表里,而子类实例则由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性,于是将子类与父类共有的属性保存在父类表中,而子类增加的属性,则保存在子类表中(这种模式与Java类的定义最相似,子类表只包含自己特有的字段,公共字段在父类表中)。13.4.3 采用每个具体类一张表13.4.3 采用每个具体类一张表采用每个具体类一张表需要使用标记,与刚才介绍的 映射策略非常相似,子类增加的属性也可以有非空约束——即父类实例的数据保存在父表中,而子类实例的数据则保存在子表中,与采用joined-subclass 映射策略不同的是,子类实例的数据仅保存在子类表中,而在父类表中没有任何记录。在这种映射策略下,子类表的字段会比父类表字段要多,因为子类表的字段等于父类表字段加子类增加属性的总和。 这种映射策略下,既不需要使用辨别者列,也无须使用key 元素来映射共有主键。如果单从数据库来看,几乎难以看出它们之间存在继承关系。13.5 小结13.5 小结本章介绍了4种高级的映射关系:关联关系映射、集合类的映射、组件映射和继承关系映射。无论哪一种都是以类与类之间的关系为起点,去寻找与数据表映射的解决。这也是Hibernate一贯的指导思想:从面向对象的程序设计的角度出发,而不是对面关系型数据。而传统的数据库应用往往是先对数据库建模、再创建表,在此基础上再开发程序。 关系型数据库的一大优势就是检索数据特别的方便和灵活,下一节将介绍Hibernate对数据检索查询的支持。
/
本文档为【第13章 复杂映射关系】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索