电话:0731-83595998
导航

精通Hibernate之映射继承关系(二)

来源: 2017-12-21 16:16

 把每个具体类映射到一张表是最简单的映射方式。如图14-2所示,在关系数据模型中只需定义COMPANIES、HOURLY_EMPLOYEES和SALARIED_EMPLOYEES表。为了叙述的方便,下文把HOURLY_EMPLOYEES表简称为HE表,把SALARIED_EMPLOYEES表简称为SE表。

  HourlyEmployee类和HE表对应,HourlyEmployee类本身的rate属性,以及从Employee类中继承的id属性和name属性,在HE表中都有对应的字段。此外,HourlyEmployee类继承了Employee类与Company类的关联关系,与此对应,在HE表中定义了参照COMPANIES表的COMPANY_ID外键。

  SalariedEmployee类和SE表对应,SalariedEmployee类本身的salary属性,以及从Employee类中继承的id属性和name属性,在SE表中都有对应的字段。此外,SalariedEmployee类继承了Employee类与Company类的关联关系,与此对应,在SE表中定义了参照COMPANIES表的COMPANY_ID外键。

  Company类、HourlyEmployee类和SalariedEmployee类都有相应的映射文件,而Employee类没有相应的映射文件。图14-3显示了持久化类、映射文件和数据库表之间的对应关系。

  如果Employee类不是抽象类,即Employee类本身也能被实例化,那么还需要为Employee类创建对应的EMPLOYEES表,此时HE表和SE表的结构仍然和图14-2中所示的一样。这意味着在EMPLOYEES表、HE表和SE表中都定义了相同的NAME字段以及参照COMPANIES表的外键COMPANY_ID.另外,还需为Employee类创建单独的Employee.hbm.xml文件。

  14.1.1 创建映射文件

  从Company类到Employee类是多态关联,但是由于关系数据模型没有描述Employee类和它的两个子类的继承关系,因此无法映射Company类的employees集合。例程14-1是Company.hbm.xml文件的代码,该文件仅仅映射了Company类的id和name属性。

  例程14-1 Company.hbm.xml

 

  HourlyEmployee.hbm.xml文件用于把HourlyEmployee类映射到HE表,在这个映射文件中,除了需要映射HourlyEmployee类本身的rate属性,还需要映射从Employee类中继承的name属性,此外还要映射从Employee类中继承的与Company类的关联关系。例程14-2是HourlyEmployee.hbm.xml文件的代码。

  例程14-2 HourlyEmployee.hbm.xml

 

  SalariedEmployee.hbm.xml文件用于把SalariedEmployee类映射到SE表,在这个映射文件中,除了需要映射SalariedEmployee类本身的salary属性,还需要映射从Employee类中继承的name属性,此外还要映射从Employee类中继承的与Company类的关联关系。例程14-3是SalariedEmployee.hbm.xml文件的代码。

|||

  例程14-3 SalariedEmployee.hbm.xml

 


  
  
  
  
  

  由于Employee类没有相应的映射文件,因此在初始化Hibernate时,只需向Configuration对象中加入Company类、HourlyEmployee类和SalariedEmployee类

  Configuration config = new Configuration();

  config.addClass(Company.class)

  。addClass(HourlyEmployee.class)

  。addClass(SalariedEmployee.class);

  14.1.2 操纵持久化对象

  这种映射方式不支持多态查询,在本书第11章的11.1.6节(多态查询)介绍了多态查询的概念。对于以下查询语句

  List employees=session.find("from Employee");

  为了检索所有的Employee对象,必须分别检索所有的HourlyEmployee实例和SalariedEmployee实例,然后把它们合并到同一个集合中。在运行Session的第一个find()方法时,Hibernate执行以下select语句

  select * from HOURLY_EMPLOYEES;

  select * from COMPANIES where ID=1;

  从HourlyEmployee类到Company类不是多态关联,在加载HourlyEmployee对象时,会同时加载与它关联的Company对象。

  在运行Session的第二个find()方法时,Hibernate执行以下select语句

  select * from SALARIED_EMPLOYEES;

  从SalariedEmployee类到Company类不是多态关联,在加载SalariedEmployee对象时,会同时加载与它关联的Company对象。在本书提供的测试数据中,所有HourlyEmployee实例和SalariedEmployee实例都与OID为1的Company对象关联,由于该Company对象已经被加载到内存中,所以Hibernate不再需要执行检索该对象的select语句。||| 

 

tx = session.beginTransaction();Company company=(Company)session.load(Company.class,new Long(id));List hourlyEmployees=session.find("from HourlyEmployee h where
s.company.id="+id);company.getEmployees().addAll(salariedEmployees);tx.commit();return company;

  由于这种映射方式不支持多态关联,因此由Session的load()方法加载的Company对象的employees集合中不包含任何Employee对象。BusinessService类必须负责从数据库中检索出所有与Company对象关联的HourlyEmployee对象以及SalariedEmployee对象,然后把它们加入到employees集合中。

  (3)运行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实例,就向HE表插入一条记录,执行如下insert语句

  insert into HOURLY_EMPLOYEES(ID,NAME,RATE,CUSTOMER_ID)

  values(3, 'Mary',300,1);

  如果employee变量引用SalariedEmployee实例,就向SE表插入一条记录。

编辑推荐:

下载Word文档

温馨提示:因考试政策、内容不断变化与调整,长理培训网站提供的以上信息仅供参考,如有异议,请考生以权威部门公布的内容为准! (责任编辑:长理培训)

网络课程 新人注册送三重礼

已有 22658 名学员学习以下课程通过考试

网友评论(共0条评论)

请自觉遵守互联网相关政策法规,评论内容只代表网友观点!

最新评论

点击加载更多评论>>

精品课程

更多
10781人学习

免费试听更多

相关推荐
图书更多+
  • 电网书籍
  • 财会书籍
  • 其它工学书籍
拼团课程更多+
  • 电气拼团课程
  • 财会拼团课程
  • 其它工学拼团
热门排行

长理培训客户端 资讯,试题,视频一手掌握

去 App Store 免费下载 iOS 客户端