《Hibernate对象关系映射.ppt》由会员分享,可在线阅读,更多相关《Hibernate对象关系映射.ppt(67页珍藏版)》请在三一办公上搜索。
1、对象关系映射,Hibernate 配置文件,Hibernate配置文件,Hibernate 配置文件主要用于配置数据库连接和 Hibernate 运行时所需的各种属性每个 Hibernate 配置文件对应一个 Configuration 对象Hibernate配置文件可以有两种格式:hibernate.properties,hibernate.cfg.xml的常用属性,JDBC 连接属性connection.url:数据库URL connection.username:数据库用户名connection.password:数据库用户密码 connection.driver_class:数据库JD
2、BC驱动 dialect:配置数据库的方言,根据底层的数据库不同产生不同的sql语句,Hibernate 会针对数据库的特性在访问时进行优化,hibernate.cfg.xml的常用属性,C3P0 数据库连接池属性:该类用来向 Hibernate 提供JDBC连接hibernate.c3p0.max_size:数据库连接池的最大连接数hibernate.c3p0.min_size:数据库连接池的最小连接数hibernate.c3p0.timeout:数据库连接池中连接对象在多长时间没有使用过后,就应该被销毁hibernate.c3p0.max_statements:缓存 Statement 对
3、象的数量hibernate.c3p0.idle_test_period:表示连接池检测线程多长时间检测一次池内的所有链接对象是否超时.连接池本身不会把自己从连接池中移除,而是专门有一个线程按照一定的时间间隔来做这件事,这个线程通过比较连接对象最后一次被使用时间和当前时间的时间差来和 timeout 做对比,进而决定是否销毁这个连接对象。hibernate.c3p0.acquire_increment:当数据库连接池中的连接耗尽时,同一时刻获取多少个数据库连接hibernate.c3p0.validate:是否每次连接都验证连接是否可用,hibernate.cfg.xml的常用属性,其他show
4、_sql:是否将运行期生成的SQL输出到日志以供调试。取值 true|false format_sql:是否将 SQL 转化为格式良好的 SQL.取值 true|falseuse_sql_comments:是否在 Hibernate 生成的 SQL 语句中添加有助于调试的注释hbm2ddl.auto:在启动和停止时自动地创建,更新或删除数据库模式。取值 create|update|create-drop|validate*,jdbc.fetch_size 和 jdbc.batch_size,hibernate.jdbc.fetch_size:实质是调用 Statement.setFetchSi
5、ze()方法设定 JDBC 的 Statement 读取数据的时候每次从数据库中取出的记录条数。例如一次查询1万条记录,对于Oracle的JDBC驱动来说,是不会 1 次性把1万条取出来的,而只会取出 fetchSize 条数,当记录集遍历完了这些记录以后,再去数据库取 fetchSize 条数据。因此大大节省了无谓的内存消耗。Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。Oracle数据库的JDBC驱动默认的Fetch Size=10,是一个保守的设定,根据测试,当Fetch Size=50时,性能会提升1倍之多,当 fe
6、tchSize=100,性能还能继续提升20%,Fetch Size继续增大,性能提升的就不显著了。并不是所有的数据库都支持Fetch Size特性,例如MySQL就不支hibernate.jdbc.batch_size:设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,类似于设置缓冲区大小的意思。batchSize 越大,批量操作的向数据库发送sql的次数越少,速度就越快。测试结果是当Batch Size=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,Batch Size=50的时候,删除仅仅需要5秒!Oracle数据库 batchSize=30
7、的时候比较合适。,对象关系映射文件,实体类和数据库的映射文件*.hbm.xml,实体类和关系数据库之间的映射可以用一个XML文档来定义。通过实体类的数据库映射文件,Hibernate可以理解持久化类和数据表之间的对应关系,也可以理解持久化类属性与数据库表列之间的对应关系在运行时 Hibernate 将根据这个映射文件来生成各种 SQL 语句映射文件的扩展名为.hbm.xml,映射文件说明,hibernate-mapping类层次:class主键。id基本类型:property实体引用类:many-to-one|one-to-one集合:set|list|map|arrayone-to-many
8、many-to-many子类:subclass|joined-subclass其它:component|any 等查询语句:query(用来放置查询语句,便于对数据库查询的统一管理和优化)一个 hibernate-mapping 中可以同时定义多个类.但更推荐为每个类都创建一个单独的映射文件,hibernate-mapping,hibernate-mapping 是 hibernate 映射文件的根元素schema:指定所映射的数据库schema的名称。若指定该属性,则表明会自动添加该 schema 前缀catalog:指定所映射的数据库catalog的名称。default-cascade(默
9、认为 none):设置hibernate默认的级联风格.若配置 Java 属性,集合映射时没有指定 cascade 属性,则 Hibernate 将采用此处指定的级联风格.default-access(默认为 property):指定 Hibernate 的默认的属性访问策略。默认值为 property,即使用 getter,setter 方法来访问属性.若指定 access,则 Hibernate 会忽略 getter/setter 方法,而通过反射访问成员变量.default-lazy(默认为 true):设置 Hibernat morning的延迟加载策略.该属性的默认值为 true,即
10、启用延迟加载策略.若配置 Java 属性映射,集合映射时没有指定 lazy 属性,则 Hibernate 将采用此处指定的延迟加载策略 auto-import(默认为 true):指定是否可以在查询语言中使用非全限定的类名(仅限于本映射文件中的类)。package(可选):指定一个包前缀,如果在映射文档中没有指定全限定的类名,就使用这个作为包名。,class,class 元素用于指定类和表的映射name:指定该持久化类映射的持久化类的类名table:指定该持久化类映射的表名,Hibernate 默认以持久化类的类名作为表名dynamic-insert:若设置为 true,表示当保存一个对象时,
11、会动态生成 insert 语句,insert 语句中仅包含所有取值不为 null 的字段.默认值为 falsedynamic-update:若设置为 true,表示当更新一个对象时,会动态生成 update 语句,update 语句中仅包含所有取值需要更新的字段.默认值为 falseselect-before-update:设置 Hibernate 在更新某个持久化对象之前是否需要先执行一次查询.默认值为 falsebatch-size:在关联对象图时,指定根据 OID 来抓取实例时每批抓取的实例数.lazy:指定是否使用延迟加载.mutable:若设置为 true,等价于所有的 元素的 up
12、date 属性为 false,表示整个实例不能被更新.默认为 true.discriminator-value:指定区分不同子类的值.当使用 元素来定义持久化类的继承关系时需要使用该属性,映射对象标识符,Hibernate 使用对象标识符(OID)来建立内存中的对象和数据库表中记录的对应关系.对象的 OID 和数据表的主键对应.Hibernate 通过标识符生成器来为 OID 赋值Hibernate 推荐在数据表中使用代理主键,即不具备业务含义的字段.代理主键通常为整数类型,因为整数类型比字符串类型要节省更多的数据库空间.在对象-关系映射文件中,元素用来设置对象标识符.子元素用来设定标识符生成
13、器.Hibernate 提供了标识符生成器接口:IdentifierGenerator,并提供了各种内置实现,id,id:设定持久化类的 OID 和表的主键的映射name:标识持久化类 OID 的属性名 column:设置标识属性所映射的数据列的列名(主键字段的名字).unsaved-value:若设定了该属性,Hibernate 会通过比较持久化类的 OID 值和该属性值来区分当前持久化类的对象是否为临时对象type:指定 Hibernate 映射类型.Hibernate 映射类型是 Java 类型与 SQL 类型的桥梁.如果没有为某个属性显式设定映射类型,Hibernate 会运用反射机制
14、先识别出持久化类的特定属性的 Java 类型,然后自动使用与之对应的默认的 Hibernate 映射类型Java 的基本数据类型和包装类型对应相同的 Hibernate 映射类型.基本数据类型无法表达 null,所以对于持久化类的 OID 推荐使用包装类型,generator,generator:设定持久化类设定标识符生成器class:指定使用的标识符生成器全限定类名或其缩写名,主键生成策略generator,Hibernate提供的内置标识符生成器:,increment 标识符生成器,increment 标识符生成器由 Hibernate 以递增的方式为代理主键赋值Hibernate 会先读
15、取 NEWS 表中的主键的最大值,而接下来向 NEWS 表中插入记录时,就在 max(id)的基础上递增,增量为 1.适用范围:由于 increment 生存标识符机制不依赖于底层数据库系统,因此它适合所有的数据库系统适用于只有单个 Hibernate 应用进程访问同一个数据库的场合,在集群环境下不推荐使用它OID 必须为 long,int 或 short 类型,如果把 OID 定义为 byte 类型,在运行时会抛出异常,identity 标识符生成器,identity 标识符生成器由底层数据库来负责生成标识符,它要求底层数据库把主键定义为自动增长字段类型适用范围:由于 identity 生成
16、标识符的机制依赖于底层数据库系统,因此,要求底层数据库系统必须支持自动增长字段类型.支持自动增长字段类型的数据库包括:DB2,Mysql,MSSQLServer,Sybase 等OID 必须为 long,int 或 short 类型,如果把 OID 定义为 byte 类型,在运行时会抛出异常,sequence 标识符生成器,sequence 标识符生成器利用底层数据库提供的序列来生成标识符.Hibernate 在持久化一个 News 对象时,先从底层数据库的 news_seq 序列中获得一个唯一的标识号,再把它作为主键值适用范围:由于 sequence 生成标识符的机制依赖于底层数据库系统的序
17、列,因此,要求底层数据库系统必须支持序列.支持序列的数据库包括:DB2 Oracle 等OID 必须为 long,int 或 short 类型,如果把 OID 定义为 byte 类型,在运行时会抛出异常,hilo 标识符生成器,hilo 标识符生成器由 Hibernate 按照一种 high/low 算法*生成标识符,它从数据库的特定表的字段中获取 high 值.Hibernate 在持久化一个 News 对象时,由 Hibernate 负责生成主键值.hilo 标识符生成器在生成标识符时,需要读取并修改 HI_TABLE 表中的 NEXT_VALUE 值.适用范围:由于 hilo 生存标识符
18、机制不依赖于底层数据库系统,因此它适合所有的数据库系统OID 必须为 long,int 或 short 类型,如果把 OID 定义为 byte 类型,在运行时会抛出异常,native 标识符生成器,native 标识符生成器依据底层数据库对自动生成标识符的支持能力,来选择使用 identity,sequence 或 hilo 标识符生成器.适用范围:由于 native 能根据底层数据库系统的类型,自动选择合适的标识符生成器,因此很适合于跨数据库平台开发OID 必须为 long,int 或 short 类型,如果把 OID 定义为 byte 类型,在运行时会抛出异常,Property,prope
19、rty 元素用于指定类的属性和表的字段的映射name:指定该持久化类的属性的名字column:指定与类的属性映射的表的字段名.如果没有设置该属性,Hibernate 将直接使用类的属性名作为字段名.type:指定 Hibernate 映射类型.Hibernate 映射类型是 Java 类型与 SQL 类型的桥梁.如果没有为某个属性显式设定映射类型,Hibernate 会运用反射机制先识别出持久化类的特定属性的 Java 类型,然后自动使用与之对应的默认的 Hibernate 映射类型.not-null:若该属性值为 true,表明不允许为 null,默认为 falseinsert:如果为 fa
20、lse,在 insert 语句中不包含该字段,表明该字段永远不能被插入.默认值为 trueupdate:如果为 false,在 update 语句中不包含该字段,表明该字段永远不能被更新.默认值为 trueaccess:指定 Hibernate 的默认的属性访问策略。默认值为 property,即使用 getter,setter 方法来访问属性.若指定 access,则 Hibernate 会忽略 getter/setter 方法,而通过反射访问成员变量,property 元素用于指定类的属性和表的字段的映射unique:设置是否为该属性所映射的数据列添加唯一约束.若设置为 true,就允许该
21、字段作为 property-ref 引用的目标index:指定一个字符串的索引名称.当系统需要 Hibernate 自动建表时,用于为该属性所映射的数据列创建索引,从而加快给予该数据列的查询.length:指定该属性所映射数据列的字段的长度scale:指定该属性所映射数据列的小数位数,对 double,float,decimal 等类型的数据列有效.formula:设置一个 SQL 表达式,Hibernate 将根据它来计算出派生属性的值.派生属性:并不是持久化类的所有属性都直接和表的字段匹配,持久化类的有些属性的值必须在运行时通过计算才能得出来,这种属性称为派生属性使用 formula 属性
22、时formula=“(sql)”的英文括号不能少Sql 表达式中的列名和表名都应该和数据库对应,而不是和持久化对象的属性对应如果需要在 formula 属性中使用参数,这直接使用 where cur.id=id 形式,其中 id 就是参数,和当前持久化对象的 id 属性对应的列的 id 值将作为参数传入.,Property,*,Java 类型,Hibernate 映射类型及 SQL 类型之间的对应关系,Java 类型,Hibernate 映射类型及 SQL 类型之间的对应关系,Java 时间和日期类型的 Hibernate 映射类型,在 Java 中,代表时间和日期的类型包括:java.uti
23、l.Date 和 java.util.Calendar.此外,在 JDBC API 中还提供了 3 个扩展了 java.util.Date 类的子类:java.sql.Date,java.sql.Time 和 java.sql.Timestamp,这三个类分别和标准 SQL 类型中的 DATE,TIME 和 TIMESTAMP 类型对应在标准 SQL 中,DATE 类型表示日期,TIME 类型表示时间,TIMESTAMP 类型表示时间戳,同时包含日期和时间信息.,Java 大对象类型的 Hiberante 映射类型,在 Java 中,java.lang.String 可用于表示长字符串(长度超
24、过 255),字符数组 byte 可用于存放图片或文件的二进制数据.此外,在 JDBC API 中还提供了 java.sql.Clob 和 java.sql.Blob 类型,它们分别和标准 SQL 中的 CLOB 和 BLOB 类型对应.CLOB 表示字符串大对象(Character Large Object),BLOB表示二进制大对象(Binary Large Object)Mysql 不支持标准 SQL 的 CLOB 类型,在 Mysql 中,用 TEXT,MEDIUMTEXT 及 LONGTEXT 类型来表示长度操作 255 的长文本数据实际上在 Java 应用程序中处理长度超过 255
25、 的字符串,使用 java.lang.String 比 java.sql.Clob 更方便;使用 byte 比 java.sql.Blob 更方便.,使用 Hibernate 内置映射类型,以下情况下必须显式指定 Hibernate 映射类型一个 Java 类型对应多个 Hibernate 映射类型时.例如:如果持久化类的属性为 java.util.Date 类型,对应的 Hibernate 映射类型可以是 date,time 或 timestamp.此时必须根据对应的数据表的字段的 SQL 类型,来确定 Hibernate 映射类型.如果字段为 DATE 类型,那么 Hibernate 映射
26、类型为 date;如果字段为 TIME 类型,那么 Hibernate 映射类型为 time;如果字段为 TIMESTATMP 类型,那么 Hibernate 映射类型为 timestamp.,练习1,根据给定的 Java 类写出相对应的 hbm.xml 文件,由 Hibernate 生成 对应的数据表,并完成对 Customer 记录在数据表中增删改查操作,映射组成关系*,建立域模型和关系数据模型有着不同的出发点:域模型:由程序代码组成,通过细化持久化类的的粒度可提高代码的可重用性,简化编程关系数据模型:由关系数据组成,在存在数据冗余的情况下,需要把粗粒度的表拆分成具有外键参照关系的几个细粒
27、度的表,从而节省存储空间;另一方面,在没有数据冗余的情况下,应该尽可能减少表的数目,简化表之间的参照关系,以便提高数据的访问速度,映射组成关系,Hibernate 把持久化类的属性分为两种:值(value)类型:没有 OID,不能被单独持久化,生命周期依赖于所属的持久化类的对象的生命周期实体(entity)类型:有 OID,可以被单独持久化,有独立的生命周期显然无法直接用 property 映射 name 属性Hibernate 使用 元素来映射组成关系,该元素表明 pay 属性是 Worker 类一个组成部分,在 Hibernate 中称之为组件,component,元素来映射组成关系cla
28、ss:设定组成关系属性的类型,此处表明 pay 属性为 Pay 类型,元素指定组件属性所属的整体类name:整体类在组件类中的属性名,映射一对多关联关系,一对多关联关系,在域模型中,类与类之间最普遍的关系就是关联关系.在 UML 中,关联是有方向的.以 Customer 和 Order 为例:一个用户能发出多个订单,而一个订单只能属于一个客户.从 Order 到 Customer 的关联使多对一关联;而从 Customer 到 Order 是一对多关联单向关联双向关联,单向 n-1,单向 n-1 关联只需从 n 的一端可以访问 1 的一端域模型:从 Order 到 Customer 的多对一单
29、向关联需要在Order 类中定义一个 Customer 属性,而在 Customer 类中无需定义存放 Order 对象的集合属性关系数据模型:ORDERS 表中的 CUSTOMER_ID 参照 CUSTOMER 表的主键,ORDERS 表,CUSTOMERS 表,单向 n-1,显然无法直接用 property 映射 customer 属性因为 Customer 有主键,所以也不能使用 component 进行映射Hibernate 使用 元素来映射多对一关联关系,many-to-one,元素来映射多对一的关联关系name:设定待映射的持久化类的属性的名字column:设定和持久化类的属性对应
30、的表的外键class:设定待映射的持久化类的属性的类型,双向 1-n,双向 1-n 与 双向 n-1 是完全相同的两种情形双向 1-n 需要在 1 的一端可以访问 n 的一端,反之依然.域模型:从 Order 到 Customer 的多对一单向关联需要在Order 类中定义一个 Customer 属性,而在 Customer 类中需定义存放 Order 对象的集合属性关系数据模型:ORDERS 表中的 CUSTOMER_ID 参照 CUSTOMER 表的主键,ORDERS 表,CUSTOMERS 表,双向 1-n,当 Session 从数据库中加载 Java 集合时,创建的是 Hibernat
31、e 内置集合类的实例,因此在持久化类中定义集合属性时必须把属性声明为 Java 接口类型Hibernate 的内置集合类具有集合代理功能,支持延迟检索策略Hibernate 的内置集合类都封装了 JDK 中的集合类,这使得 Hibernate 能够对缓存中的集合对象进行脏检查,按照集合对象的状态来同步更新数据库。在定义集合属性时,通常把它初始化为集合实现类的一个实例.这样可以提高程序的健壮性,避免应用程序访问取值为 null 的集合的方法而抛出 NullPointerException,双向 1-n,Hibernate 使用 元素来映射 set 类型的属性,set,元素来映射持久化类的 set
32、 类型的属性name:设定待映射的持久化类的属性名,key,元素设定与所关联的持久化类对应的表的外键column:指定关联表的外键名,one-to-many,元素设定集合属性中所关联的持久化类class:指定关联的持久化类的类名,cascade 属性,在对象 关系映射文件中,用于映射持久化类之间关联关系的元素,和 都有一个 cascade 属性,它用于指定如何操纵与当前对象关联的其他对象.,元素的 inverse 属性,在hibernate中通过对 inverse 属性的来决定是由双向关联的哪一方来维护表和表之间的关系.inverse=false 的为主动方,inverse=true 的为被动
33、方,由主动方负责维护关联关系在没有设置 inverse=true 的情况下,父子两边都维护父子 关系 在 1-n 关系中,将 n 方设为主控方将有助于性能改善(如果要国家元首记住全国人民的名字,不是太可能,但要让全国人民知道国家元首,就容易的多)在 1-N 关系中,若将 1 方设为主控方会额外多出 update 语句。插入数据时无法同时插入外键列,因而无法为外键列添加非空约束,在数据库中对集合排序,元素有一个 order-by 属性,如果设置了该属性,当 Hibernate 通过 select 语句到数据库中检索集合对象时,利用 order by 子句进行排序order-by 属性中还可以加入
34、 SQL 函数,映射一对一关联关系,1-1,域模型关系数据模型:按照外键映射:按照主键映射:,DEPARTMENTS 表,MANAGERS 表,DEPARTMENTS 表,MANAGERS 表,基于外键映射的 1-1,对于基于外键的1-1关联,其外键可以存放在任意一边,在需要存放外键一端,增加 many-to-one 元素。为 many-to-one元素增加 unique=“true”属性来表示为1-1关联,并用name属性来指定关联属性的属性名另一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段不使用 property
35、-ref 属性的 sql使用 property-ref 属性的 sql,基于主键映射的 1-1,基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据”对方”的主键来生成自己的主键,自己并不能独立生成主键.子元素指定使用当前持久化类的哪个属性作为“对方”采用foreign主键生成器策略的一端增加 one-to-one 元素映射关联属性,其 one-to-one 属性还应增加 constrained=“true”属性;另一端增加one-to-one元素映射关联属性。constrained(约束):指定为当前持久化类对应的数据库表的主键添加一个外键约束,引用被关联的对象(“对方
36、”)所对应的数据库表主键,映射多对多关联关系,单向 n-n,域模型:关系数据模型,CATEGORIES 表,CATEGORIES_ITEMS 表,ITEMS 表,单向 n-n,n-n 的关联必须使用连接表与 1-n 映射类似,必须为 set 集合元素添加 key 子元素,指定 CATEGORIES_ITEMS 表中参照 CATEGORIES 表的外键为 CATEGORIY_ID.与 1-n 关联映射不同的是,建立 n-n 关联时,集合中的元素使用 many-to-many.many-to-many 子元素的 class 属性指定 items 集合中存放的是 Item 对象,column 属性指
37、定 CATEGORIES_ITEMS 表中参照 ITEMS 表的外键为 ITEM_ID,双向 n-n,域模型:关系数据模型,CATEGORIES 表,CATEGORIES_ITEMS 表,ITEMS 表,双向n-n关联,双向 n-n 关联需要两端都使用集合属性双向n-n关联必须使用连接表集合属性应增加 key 子元素用以映射外键列,集合元素里还应增加many-to-many子元素关联实体类在双向 n-n 关联的两边都需指定连接表的表名及外键列的列名.两个集合元素 set 的 table 元素的值必须指定,而且必须相同。set元素的两个子元素:key 和 many-to-many 都必须指定 c
38、olumn 属性,其中,key 和 many-to-many 分别指定本持久化类和关联类在连接表中的外键列名,因此两边的 key 与 many-to-many 的column属性交叉相同。也就是说,一边的set元素的key的 cloumn值为a,many-to-many 的 column 为b;则另一边的 set 元素的 key 的 column 值 b,many-to-many的 column 值为 a.对于双向 n-n 关联,须把其中一端的 inverse 设置为 true,否则可能会造成主键冲突.,映射继承关系,继承映射,对于面向对象的程序设计语言而言,继承和多态是两个最基本的概念。Hi
39、bernate 的继承映射可以理解持久化类之间的继承关系。例如:人和学生之间的关系。学生继承了人,可以认为学生是一个特殊的人,如果对人进行查询,学生的实例也将被得到。,继承映射,Hibernate支持三种继承映射策略:每个具体类一张表(table per concrete class)将域模型中的每一个实体对象映射到一个独立的表中,也就是说不用在关系数据模型中考虑域模型中的继承关系和多态。每个类分层结构一张表(table per class hierarchy)对于继承关系中的子类使用同一个表,这就需要在数据库表中增加额外的区分子类类型的字段。每个子类一张表(table per subclas
40、s)域模型中的每个类映射到一个表,通过关系数据模型中的外键来描述表之间的继承关系。这也就相当于按照域模型的结构来建立数据库中的表,并通过外键来建立表之间的继承关系。,采用 subclass 元素的继承映射,采用 subclass 的继承映射可以实现对于继承关系中父类和子类使用同一张表因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到低是哪个类的实例-这个列被称为辨别者列(discriminator).在这种映射策略下,使用 subclass 来映射子类,使用 class 或 subclass 的 discriminator-value 属性指定辨别者列
41、的值所有子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列其实并没有值,这将引起数据库完整性冲突,导致父类的实例无法保存到数据库中,采用 subclass 元素的继承映射,采用 joined-subclass 元素的继承映射,采用 joined-subclass 元素的继承映射可以实现每个子类一张表采用这种映射策略时,父类实例保存在父类表中,子类实例由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性。于是将子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中。在这种映射策略下,无须使用鉴别者列,但需要为每
42、个子类使用 key 元素映射共有主键,该主键必须与父类标识属性的列名相同。但如果继承树的深度很深,可能查询一个子类实例时,需要跨越多个表,因为子类的数据一次保存在多个父类中。子类增加的属性可以添加非空约束。因为子类的属性和父类的属性没有保存在同一个表中,采用 joined-subclass 元素的继承映射,采用 union-subclass 元素的继承映射,采用 union-subclass 元素可以实现将每一个实体对象映射到一个独立的表中。子类增加的属性可以有非空约束-即父类实例的数据保存在父表中,而子类实例的数据保存在子类表中。子类实例的数据仅保存在子类表中,而在父类表中没有任何记录在这种映射策略下,子类表的字段会比父类表的映射字段要多,因为子类表的字段等于父类表的字段、加子类增加属性的总和在这种映射策略下,既不需要使用鉴别者列,也无须使用 key 元素来映射共有主键.使用 union-subclass 映射策略是不可使用 identity 的主键生成策略,因为同一类继承层次中所有实体类都需要使用同一个主键种子,即多个持久化实体对应的记录的主键应该是连续的.受此影响,也不该使用 native 主键生成策略,因为 native 会根据数据库来选择使用 identity 或 sequence.,采用 union-subclass 元素的继承映射,三种继承映射方式的比较,练习3,