Hibernate读书笔记---继承映射(一)

2014-11-24 08:36:37 · 作者: · 浏览: 2

对于面向对象的程序设计语言,继承、多态是两个最基本的概念。Hibernate的继承映射可以理解两个持久化类之间的继承关系。
Hibernate支持几种继承映射策略,不管哪种继承映射策略,Hibernate的多态查询都可以很好的运行。
假设有四个对象:Department、Employee、Skiller、Sales。他们四个对象存在如下关系:

从上面的关系可知:Employee与Department之间存在N-1的关联关系。Skiller和Sales都是Employee的子类。下面是这四个类的代码:
Department
[java]
public class Department {
private Integer id;
private String name;
private Set employees; //关联关系

//省略setter和getter方法
}
Employee
[java]
public class Employee {
private Integer id;
private String name;
private Department department;
//省略setter和getter方法
}
Skiller
[java]
public class Skiller extends Employee {
private String skiller;
//省略setter和getter方法
}
Sales
[java]
public class Sales extends Employee {
private int sell;
//省略setter和getter方法
}

一、采用subclass元素的继承映射
在这种继承映射策略下,整个继承树的所有实例都将保存在同一张表中。因为是将父类、子类的实例全部保存在同一张表中,所以需要在该表中添加列,通过该列可以区分每行记录到底是属于哪个类的实例---这个列被称之为辨别者。
在这种继承映射策略下,我们需要使用元素来映射子类的持久化类,使用元素来映射辨别者,同时还需要给元素增加discriminator-value属性来指定每个类的辨别者的值。
映射文件如下:
[html]























在这里我们只需要给父类进行映射就可以了。在这个配置文件中,指定了一个辨别者列:type,该列其本省是没有任何意义的,只是起到一个区分每条记录时对应哪个持久化类的作用。其中Skiller类的辨别者列type的值为skiller,Sales类的辨别者列type的值为sales。通过下面的程序段来进行操作。
[html]
static void add(){
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();

Department department = new Department();
department.setName("department name1");

Employee emp1 = new Employee();
emp1.setName("employy name1");
emp1.setId(1);

Skiller emp2 = new Skiller();
emp2.setSkiller("电工");
emp2.setName("employee name2");
emp2.setDepartment(department); //建立对象之间的关联关系

Sales emp3= new Sales();
emp3.setSell(50);
emp3.setName("employee name3");
emp3.setDepartment(department); //建立对象之间的关联关系

session.save(department);
session.save(emp1);
session.save(emp2);
session.save(emp3);

tx.commit();
session.close();

}
上面的程序段,hibernate将会产生如下的几条SQL语句:
[sql] view plaincopyprint
Hibernate: insert into department (departmentName) values ( )

Hibernate: insert into employee (employeeName, departmentID, type) values ( , , 'com.hibernate.domain.Employee')

Hibernate: insert into employee (employeeName, departmentID, skiller, type) values ( , , , 'skiller')

Hibernate: insert into employee (employeeName, departmentID, sell, type) values ( , , , 'sales')

在第二条sql语句,type的值为com.hibernate.domain.Employee。对于这个值可以理解为空。在第三条sql语句中,type的值为skiller,第四天sql语句中type值为sales。同时要注意第三条sql语句中的sell列是没有值的,第四条的skiller列同样也没有值。所以在这里一定要注意:使用subclass继承映射策略时,其子类中增加的属性映射的字段是一定不能有非空约束的。
表结构如下:

通过下面的程序段,来进行查询操作:
[java]
static void query(int empid){
Session session = HibernateUtil.getSession();
Employee emp = (Employee) session.get(Employee.class, empid);
}
得到如下SQL语句:
[sql]
Hibernate: select employee0_.employeeID as employeeID2_0_, e