1. Employee 为基类, 派生出HourEmployee 和 SalaryEmployee两个类。
采用 subclass 元素的继承映射(1)
采用 subclass
的继承映射可以实现对于继承关系中父类和子类使用同一张表
因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到底是哪个类的实例----这个列被称为辨别者列(discriminator).
在这种映射策略下,使用
subclass 来映射子类,使用class
或 subclass
的 discriminator-value
属性指定辨别者列的值
所有子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列其实并没有值,这将引起数据库完整性冲突,导致父类的实例无法保存到数据库中
示例代码::
Employee.java
public class Employee {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
HourEmployee.java
/**
* 钟点工
*/
public class HourEmployee extends Employee{
private Double rate;
public Double getRate() {
return rate;
}
public void setRate(Double rate) {
this.rate = rate;
}
}
SalaryEmployee.java
/**
* 正是员工
*/
public class SalaryEmployee extends Employee {
private Double salary;
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
}
Employee.hbm.xml 配置文件
App.java
public class App { private static SessionFactory sf=null; static{ Configuration config=new Configuration(); config.configure("cn/itcast/extends01/hibernate.cfg.xml"); config.addClass(Employee.class); sf=config.buildSessionFactory(); } /* * 知识点1: 保存员工信息 */ @Test public void saveStudentAndCoure(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); Employee e=new Employee(); e.setName("xxxx"); HourEmployee he=new HourEmployee(); he.setName("小昭"); he.setRate(10d); SalaryEmployee se=new SalaryEmployee(); se.setName("赵敏"); se.setSalary(3000d); session.save(e); session.save(he); session.save(se); tx.commit(); session.close(); } //知识点2: 查询钟点工信息 @Test public void findHourEmployee(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); //HQL语句 可以使用子类HourEmployee Query query=session.createQuery("from HourEmployee"); query.list(); tx.commit(); session.close(); } }hibernate.cfg.xml
采用 joined-subclass 元素的继承映射(2)采用 joined-subclass 元素的继承映射可以实现每个子类一张表采用这种映射策略时,父类实例保存在父类表中,子类实例由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性。于是将子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中。在这种映射策略下,无须使用鉴别者列,但需要为每个子类使用 key 元素映射共有主键,该主键必须与父类标识属性的列名相同。但如果继承树的深度很深,可能查询一个子类实例时,需要跨越多个表,因为子类的数据一次保存在多个父类中。子类增加的属性可以添加非空约束。因为子类的属性和父类的属性没有保存在同一个表中代码示例: 未贴出的和(1)相同
Employee.hbm.xml 配置文件
App.java
import org.hibernate.Query; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.Transaction; import org.hibernate.cfg.Configuration; import org.junit.Test; public class App { private static SessionFactory sf=null; static{ Configuration config=new Configuration(); config.configure("cn/itcast/extends02/hibernate.cfg.xml"); config.addClass(Employee.class); sf=config.buildSessionFactory(); } /* * 知识点1: 保存员工信息 */ @Test public void saveStudentAndCoure(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); Employee e=new Employee(); e.setName("xxxx"); HourEmployee he=new HourEmployee(); he.setName("小昭"); he.setRate(10d); SalaryEmployee se=new SalaryEmployee(); se.setName("赵敏"); se.setSalary(3000d); session.save(e); session.save(he); session.save(se); tx.commit(); session.close(); } //知识点2: 查询钟点工信息 @Test public void findHourEmployee(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); //可以使用子类 Query query=session.createQuery("from HourEmployee"); query.list(); tx.commit(); session.close(); } //知识点5: 查询员工信息 @Test public void findEmployee(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); //可以使用子类 Query query=session.createQuery("from Employee"); query.list(); tx.commit(); session.close(); } //知识点6: 删除员工信息(不用使用级联) 删除2号员工 @Test public void removeEmployee(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); Employee e2=(Employee)session.get(Employee.class, 2); session.delete(e2); tx.commit(); session.close(); } //知识点7:查询唯一的员工,不是钟点工也不是正式员工 @Test public void findUniqueEmployee(){ Session session=sf.openSession(); Transaction tx=session.beginTransaction(); //sql SELECT * FROM e_emp e WHERE e.id NOT IN(SELECT hid FROM h_emp) AND e.id NOT IN(SELECT sid FROM s_emp) Query query=session.createQuery("from Employee e where e.id not in(select h.id from HourEmployee h) and e.id not in(select s.id from SalaryEmployee s)"); query.list(); tx.commit(); session.close(); } }