本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7591684
建立时间:2006年5月29日




[Hibernate]精通Hibernate映射继承关系之五
软件技术

lhwork 发表于 2006/12/22 17:13:33

本章介绍的三种映射方式各有优缺点,表14-1对这三种映射方式做了比较。 500)this.width=500'> 表14-1 比较三种映射方式如果不需要支持多态查询和多态关联,可以采用每个具体类对应一个表的映 射方式,如果需要支持多态查询和多态关联,并且子类包含的属性不多,可以采用根类对应一个表的映射方式,如果需要支持多态查询和多态关联,并且子类包含的 属性很多,可以采用每个类对应一个表的映射方式。如果继承关系树中包含接口,可以把它当做抽象类来处理。图14-9显示了一棵复杂的继承关系树,其中DOClass类为抽象类,其他均为具体类。 500)this.width=500'> 图14-9 复杂的继承关系树 可以将图14-9的继承关系树分解为3棵子树:DOClass类、ClassA类和ClassB类为一棵子树:DOClass类为抽象类,位于整个继承关系树的顶层,通常不会对它进行多态查询,因此可以采用每个具体类对应一个表的映射方式,ClassA类对应TABLE_A表,ClassB类对应TABLE_B表。ClassA类、ClassC类、ClassD类、ClassG类和ClassH类为一棵子树:ClassA类的所有子类都只包含少量属性,因此可以采用根类对应一个表的映射方式,ClassA类对应TABLE_A表。ClassB类、ClassE类和ClassF为一棵子树:ClassB类的两个子类都包含很多属性,因此采用每个类对应一个表的映射方式,ClassB类对应TABLE_B表,ClassE类对应TABLE_E表,ClassF类对应TABLE_F表。如 图14-10所示,在关系数据模型中,只需创建TABLE_A、TABLE_B、TABLE_E和TABLE_F表,其中TABLE_A中包含了与 DOClass、ClassA、ClassC、ClassD、ClassG和ClassH的属性对应的字段。TABLE_B中包含了与DOClass和 ClassB的属性对应的字段,TABLE_E和TABLE_F的B_ID字段既是主键,又是参照TABLE_B表的外键。 500)this.width=500'> 图14-10 复杂继承关系树对应的关系数据模型 只需创建两个映射文件,ClassA.hbm.xml和ClassB.hbm.xml,例程14-9和例程14-10分别为它们的源代码。例程14-9 ClassA.hbm.xml <hibernate-mapping > <class name="mypack.ClassA" table="TABLE_A" discriminator-value="A" > <id name="id" type="long" column="ID"> <generator class="increment"/> </id> <discriminator column="A_TYPE" type="string" /> <property name="a1" type="string" column="A1" /> <subclass name="mypack.ClassC" discriminator-value="C" > <property name="c1" column="C1" type="string" /> </subclass> <subclass name="mypack.ClassD" discriminator-value="D" > <property name="d1" column="D1" type="string" /> <subclass name="mypack.ClassG" discriminator-value="G" > <property name="g1" column="G1" type="string" /> </subclass> <subclass name="mypack.ClassH" discriminator-value="H" > <property name="h1" column="H1" type="string" /> </subclass> </subclass> </class> </hibernate-mapping> 例程14-10 ClassB.hbm.xml   <hibernate-mapping > <class name="mypack.ClassB" table="TABLE_B"> <id name="id" type="long" column="ID"> <generator class="increment"/> </id> <property name="b1" type="string" column="B1" /> <joined-subclass name="mypack.ClassE" table="TABLE_E"> <key column="B_ID" /> <property name="e1" column="E1" type="string" /> <property name="e2" column="E2" type="string" /> <property name="e3" column="E3" type="string" /> <property name="e4" column="E4" type="string" /> <property name="e5" column="E5" type="string" /> <property name="e6" column="E6" type="string" /> </joined-subclass > <joined-subclass name="mypack.ClassF" table="TABLE_F"> <key column="B_ID" /> <property name="f1" column="F1" type="string" /> <property name="f2" column="F2" type="string" /> <property name="f3" column="F3" type="string" /> <property name="f4" column="F4" type="string" /> <property name="f5" column="F5" type="string" /> <property name="f6" column="F6" type="string" /> </joined-subclass > </class> </hibernate-mapping>在ClassA.hbm.xml文件中,在用于映射ClassD的元素中还嵌入了两个元素,它们分别映射ClassG和ClassH类。在以及所有的元 素中都设置了discriminator-value属性,Hibernate根据discriminator-value属性来判断TABLE_A表中 的记录对应哪个类的实例,如果 TABLE_A表的一条记录的A_TYPE字段取值为"A",表明它是ClassA类的实例,如果A_TYPE字段取值为"G",表明它是ClassG类 的实例,依次类推。值得注意的是,在元素中只能嵌入子元素,但不能嵌入子元素,而在元素中只能嵌入子元素,但不能嵌入< subclass>子元素。本 节的范例程序位于配套光盘的sourcecode\chapter14\14.4目录下,运行该程序前,需要在SAMPLEDB数据库中手工创建 TABLE_A表、TABLE_B表、TABLE_E表和TABLE_F表,相关的SQL脚本文件为\14.4\schema\ sampledb.sql。在DOS命令行下进入chapter14根目录,然后输入命令: ant -file build4.xml run 就会运行BusinessService类。BusinessService的main()方法调用test()方法,test()方法调用saveDO(DOClass Object)方法,它负责保存一个DOClass对象,saveDO()方法的代码如下: tx = session.beginTransaction();session.save(object);tx.commit(); 在test()方法中,创建了一个ClassG类的实例和一个ClassF类的实例,然后调用saveDO()方法分别保存这两个实例: ClassG g=new ClassG("a1","d1","g1");saveDO(g); ClassF f=new ClassF("b1","f1","f2","f3","f4","f5","f6","f7");saveDO(f); Session的save()方法能判断object变量实际引用的实例的类型,如果object变量引用ClassG类的实例,就执行如下insert语句: insert into TABLE_A (ID,A1,D1,G1,A_TYPE) values (1, 'a1', 'd1', 'g1','G'); 如果object变量引用ClassF类的实例,就执行如下insert语句: insert into TABLE_B (ID,B1) values (1, 'b1');insert into TABLE_F (B_ID ,F1, F2, F3, F4, F5, F6) values (1, 'f1', 'f2', 'f3', 'f4', 'f5', 'f6', 'f7');


阅读全文(1902) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.070 second(s), page refreshed 144752768 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号