网站首页
JSP空间
动态资讯
开源项目
技术文档
资源下载
J2EE资源
客户论坛
在线支付
 
  技术文档>>JAVA>>新手入门>>基础入门>查看文档  
  精通hibernate之映射继承关系六     
  文章作者:未知  文章来源:水木森林  
  查看:75次  录入:管理员--2007-11-17  
 
  在这种映射方式下,继承关系树的每个类以及接口都对应一个表。在本例中,需要创建employees、he和se表。
  
  如图14-6所示,employees表仅包含和employee类的属性对应的字段,he表仅包含和hourlyemployee类的属性对应的字段,se表仅包含和salariedemployee类的属性对应的字段。此外,he表和se表都以employee_id字段作为主键,该字段还同时作为外键参照employees表。
  
 精通hibernate之映射继承关系六(图一)

  
图14-6 继承关系树的每个类对应一个表

  
精通hibernate之映射继承关系六(图二)

  
图14-7 持久化类、映射文件和数据库表之间的对应关系

  
  14.3.1 创建映射文件
  
  从company类到employee类是多态关联,由于关系数据模型描述了employee类和它的两个子类的继承关系,因此可以映射company类的employees集合。例程14-7是company.hbm.xml文件的代码,该文件不仅映射了company类的id和name属性,还映射了它的employees集合。
  
  例程14-7 company.hbm.xml
  
  <hibernate-mapping >
  <class name="mypack.company" table="companies" >
  <id name="id" type="long" column="id">
  <generator class="increment"/>
  </id>
  
  <property name="name" type="string" column="name" />
  <set
  name="employees"
  inverse="true"
  lazy="true" >
  <key column="company_id" />
  <one-to-many class="mypack.employee" />
  </set>
  
  </class>
  </hibernate-mapping>
  
  employee.hbm.xml文件用于把employee类映射到employees表,在这个映射文件中,除了需要映射employee类本身的属性,还需要在元素中映射两个子类的属性。例程14-8是employee.hbm.xml文件的代码。
  
  例程14-8 employee.hbm.xml
  
  <hibernate-mapping >
  
  <class name="mypack.employee" table="employees">
  <id name="id" type="long" column="id">
  <generator class="increment"/>
  </id>
  <property name="name" type="string" column="name" />
  
  <many-to-one
  name="company"
  column="company_id"
  class="mypack.company"
  />
  
  <joined-subclass name="mypack.hourlyemployee" table="hourly_employees" >
  <key column="employee_id" />
  <property name="rate" column="rate" type="double" />
  </joined-subclass>
  
  <joined-subclass name="mypack.salariedemployee" table="salaried_employees" >
  <key column="employee_id" />
  <property name="salary" column="salary" type="double" />
  </joined-subclass>
  
  </class>
  </hibernate-mapping>
  
  在employee.hbm.xml文件中,两个元素用于映射hourlyemployee类和salariedemployee类,元素的子元素指定he表和se表中既作为主键又作为外键的employee_id字段。
  
  由于hourlyemployee类和salariedemployee类没有单独的映射文件,因此在初始化hibernate时,只需向configuration对象中加入company类和employee类:
  
  configuration config = new configuration();
  config.addclass(company.class)
  .addclass(employee.class);
  
  也可以在单独的映射文件中配置或元素,但此时必须显式设定它们的extends属性。例如可以在单独的hourlyemployee.hbm.xml文件中映射hourlyemployee类:
  
  <hibernate-mapping >
  <joined-subclass
  name="mypack.hourlyemployee"
  table="hourly_employees"
  extends="mypack.employee" >
  ……
  </joined-class>
  <hibernate-mapping >
  
  由于hourlyemployee类的映射代码不位于employee.hbm.xml文件中,因此在初始化hibernate时,不仅需要向configuration对象中加入company类和employee类,还需要加入hourlyemployee类,并且必须先加入employee父类,再加入hourlyemployee子类:
  
  configuration config = new configuration();
  config.addclass(company.class)
  .addclass(employee.class)
  .addclass(hourlyemployee.class);
  
  如果颠倒加入employee类和hourlyemployee子类的顺序,hibernate在执行addclass()方法时会抛出hibernatemappingexception。
  
  14.3.2 操纵持久化对象
  
  这种映射方式支持多态查询,对于以下查询语句:
  
  list employees=session.find("from employee");
  
  hibernate会检索出所有的hourlyemployee对象和salariedemployee对象。此外,也可以单独查询employee类的两个子类的实例,例如:
  
  list hourlyemployees=session.find("from hourlyemployee");
  
  本节的范例程序位于配套光盘的sourcecode/chapter14/14.3目录下,运行该程序前,需要在sampledb数据库中手工创建companies表、employees表、he表和se表,然后加入测试数据,相关的sql脚本文件为/14.3/schema/sampledb.sql。
  
  在dos命令行下进入chapter14根目录,然后输入命令:
  
  ant -file build3.xml run
  
  就会运行businessservice类。businessservice的main()方法调用test()方法,test()方法依次调用以下方法:
  
  findallhourlyemployees():检索数据库中所有的hourlyemployee对象。
  findallemployees():检索数据库中所有的employee对象。
  loadcompany():加载一个company对象。
  saveemployee():保存一个employee对象。
  
  (1)运行findallhourlyemployees()方法,它的代码如下:
  
  tx = session.begintransaction();
  list results=session.find("from hourlyemployee");
  tx.commit();
  return results;
  在运行session的find()方法时,hibernate执行以下select语句:
  select * from hourly_employees he inner join employees e
  on he.employee_id=e.id;
  select * from companies where id=1;
  
  hibernate通过he表与employees表的内连接获得hourlyemployee对象的所有属性值,此外,在加载hourlyemployee对象时,还会同时加载与它关联的company对象。
  
  (2)运行findallemployees()方法,它的代码如下:
  
  tx = session.begintransaction();
  list results=session.find("from employee");
  tx.commit();
  return results;
  在运行session的find()方法时,hibernate执行以下select语句:
  select * from employees e
  left outer join hourly_employees he on e.id=he.employee_id
  left outer join salaried_employees se on e.id=se.employee_id;
  select * from companies where id=1;
  
  hibernate把employees表与he表以及se表进行左外连接,从而获得hourlyemployee对象和salariedemployee对象的所有属性值。在这种映射方式下,hibernate支持多态查询,对于以上查询语句获得的查询结果,如果he表的employee_id字段不为null,就创建houlyemployee实例,如果se表的employee_id字段不为null,就创建salariedemployee实例,这些实例所关联的company对象也被加载。(3)运行loadcompany()方法,它的代码如下:
  
  tx = session.begintransaction();
  company company=(company)session.load(company.class,new long(id));
  hibernate.initialize(company.getemployees());
  tx.commit();
  
  这种映射方式支持多态关联。如果在company.hbm.xml文件中对employees集合设置了立即检索策略,那么session的load()方法加载的company对象的employees集合中包含所有关联的employee对象。由于本书提供的company.hbm.xml文件对employees集合设置了延迟检索策略,因此以上程序代码还通过hibernate类的静态initialize()方法来显式初始化employees集合。
  
  (4)运行saveemployee(employee employee)方法,它的代码如下:
  
  tx = session.begintransaction();
  session.save(employee);
  tx.commit();
  
  在test()方法中,创建了一个hourlyemployee实例,然后调用saveemployee()方法保存这个实例:
  
  employee employee=new hourlyemployee("mary",300,company);
  saveemployee(employee);
  
  session的save()方法能判断employee变量实际引用的实例的类型,如果employee变量引用hourlyemployee实例,就执行如下insert语句:
  
  insert into employees (id,name, company_id) values (5, 'mary', 1);
  insert into hourly_employees (employee_id ,rate) values (5, 300);
  
  可见,每保存一个hourlyemployee对象,需要分别向employees表和he表插入一条记录,employees表的记录和he表的记录共享同一个主键。
 
 
上一篇: 精通hibernate之映射继承关系七(图)    下一篇: web环境 hibernate数据源问题补充
  相关文档
j2me编程应用平台中几个重要概念的介绍 04-17
用jsp实现数据库图片的存储与显示实例 11-16
异常处理优劣观 11-17
用jai扩展java的图像处理能力 11-17
eclipse插件开发中实现刷新和重编译介绍 04-10
面向对象编程之:java collection更有效管理elements 11-17
j2me 2d小游戏入门之计时器 11-16
一些j2me开发的faq 11-17
scjp认证套题解析之三 11-16
用java.net包建立双向通讯 11-17
java api 接口篇(二)下 11-17
使用jsf(java server faces)开发(三) 11-17
java极限考验 classloader类的装载策略 11-16
详细讲解怎样在java中运行其它应用程序 11-17
j2ee基础:对于spring初学者的学习建议 11-03
jsp实现jdom处理数据库到xml转换的应用 11-16
Java中利用通讯API编写的短信软件 08-06
java语言深入 文件和流 11-17
将aspectj集成到基于eclipse + lomboz + xmlbuddy的web应用中去.. 11-17
java程序中的多线程 11-17
返回首页 | 关于我们 | J网章程 | JSP空间合租 | 客服中心 | 免责声明 | 常见问题 | 参观机房
本站主机空间代理至厦门市华众网络科技有限公司
《中华人民共和国增值电信业务经营许可证》
编号:闽B2-20050079
@2005-2008福建JSP技术网 版权所有 闽ICP备05000928号
技术电话:13616026886
邮箱:admin@fjjsp.com 站长QQ,点击这里给我发消息