继承关系映射
一:需求分析
- 现要为某公司开发一个员工信息管理系统,已经了解到该公司的员工中有按小时记薪和按月记薪两种方式,这种情况下系统中该如何维护员工的基本信息呢?
- 包含域模型设计:
因为域模型就有一种,所以每种方式的域模型都是一样的,只是数据库关系不一样。
二:每个具体类对应一张表(Table per concrete class)
- 数据库创建时,按时薪计算的员工创建一张表,按月薪计算的员工创建一张表。
时薪员工数据表结构:
月薪员工数据表结构:
1.使用xml的方式配置
员工类:
public class Employee {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
时薪员工类:
public class HourlyEmployee extends Employee {
private double rate;
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
@Override
public String toString() {
return "HourlyEmployee [rate=" + rate + ", getId()=" + getId() + ", toString()=" + super.toString()
+ ", getName()=" + getName() + "]";
}
}
时薪员工类xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
<class name="HourlyEmployee" table="hourly_employee">
<id name="id" type="int">
<column name="id"></column>
<generator class="native"></generator>
</id>
<property name="name" type="java.lang.String">
</property>
<property name="rate" type="double" />
</class>
</hibernate-mapping>
月薪员工类:
public class SalariedEmployee extends Employee {
private double salay;
public double getSalay() {
return salay;
}
public void setSalay(double salay) {
this.salay = salay;
}
@Override
public String toString() {
return "SalariedEmployee [salay=" + salay + ", toString()=" + super.toString() + "]";
}
}
月薪员工类xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
<class name="SalariedEmployee" table="salaied_employee">
<id name="id" type="int">
<column name="id"></column>
<generator class="increment"></generator>
</id>
<property name="name" type="java.lang.String">
</property>
<property name="salay" type="double" column="salary"></property>
</class>
</hibernate-mapping>
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<mapping resource="com/hibernate/entity/HourlyEmployee.hbm.xml" />
<mapping resource="com/hibernate/entity/SalariedEmployee.hbm.xml" />
</session-factory>
</hibernate-configuration>
测试类:
public class Test {
public static void main(String[] args) {
// 1.测试员工是否能成功入库
HourlyEmployee hourlyEmployee = new HourlyEmployee();
hourlyEmployee.setName("20");
hourlyEmployee.setRate(50);
SalariedEmployee salariedEmployee = new SalariedEmployee();
salariedEmployee.setName("888");
salariedEmployee.setSalay(30);
// 保存按小时记新员工信息
// saveEmployee(salariedEmployee);
findEmployee();
}
private static void saveEmployee(Employee e) {
// 1.获取session
Session session = HibernateUtil.openSession();
Transaction tx = session.beginTransaction();
session.save(e);
tx.commit();
// 关闭session
session.close();
}
private static void findEmployee() {
// 1.获取session
Session session = HibernateUtil.openSession();
Transaction tx = session.beginTransaction();
HourlyEmployee he = session.get(HourlyEmployee.class, new Integer(1));
System.out.println(he);
SalariedEmployee se = session.get(SalariedEmployee.class, new Integer(1));
System.out.println(se);
}
}
2.使用注解的方式配置
员工类:
@MappedSuperclass
public class Employee {
private Integer id;
private String name;
@Id
@GeneratedValue(generator = "my_increment")
@GenericGenerator(name = "my_increment", strategy = "native")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
时薪员工类:
@Entity
@Table(name = "hourly_employee")
public class HourlyEmployee extends Employee {
private double rate;
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
@Override
public String toString() {
return "HourlyEmployee [rate=" + rate + ", getId()=" + getId() + ", toString()=" + super.toString()
+ ", getName()=" + getName() + "]";
}
}
月薪员工类:
@Entity
@Table(name = "salaied_employee")
public class SalariedEmployee extends Employee {
private double salay;
@Column(name = "salary")
public double getSalay() {
return salay;
}
public void setSalay(double salay) {
this.salay = salay;
}
@Override
public String toString() {
return "SalariedEmployee [salay=" + salay + ", toString()=" + super.toString() + "]";
}
}
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<mapping class="com.hibernate.entity.Employee" />
<mapping class="com.hibernate.entity.HourlyEmployee" />
<mapping class="com.hibernate.entity.SalariedEmployee" />
</session-factory>
</hibernate-configuration>
测试类:
public class Test {
public static void main(String[] args) {
// 1.测试员工是否能成功入库
HourlyEmployee hourlyEmployee = new HourlyEmployee();
hourlyEmployee.setName("20");
hourlyEmployee.setRate(50);
SalariedEmployee salariedEmployee = new SalariedEmployee();
salariedEmployee.setName("888");
salariedEmployee.setSalay(30);
// 保存按小时记新员工信息
// saveEmployee(salariedEmployee);
findEmployee();
}
private static void saveEmployee(Employee e) {
// 1.获取session
Session session = HibernateUtil.openSession();
Transaction tx = session.beginTransaction();
session.save(e);
tx.commit();
// 关闭session
session.close();
}
private static void findEmployee() {
// 1.获取session
Session session = HibernateUtil.openSession();
Transaction tx = session.beginTransaction();
HourlyEmployee he = session.get(HourlyEmployee.class, new Integer(1));
System.out.println(he);
SalariedEmployee se = session.get(SalariedEmployee.class, new Integer(1));
System.out.println(se);
}
}
三:父类对应一个表(Table per class hierarchy)
父类创建一个表,每个子类的字段都包含,再增加一个字段用来区别每个子类的类型。
数据表结构:
持久化类、映射文件和数据库表之间的关系:
1.使用xml的方式配置
员工类,时薪员工类,月薪员工类同上。
员工类配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
<class name="Employee" table="employee">
<id name="id" type="int">
<column name="id"></column>
<generator class="native"></generator>
</id>
<discriminator column="employee_type"></discriminator>
<property name="name" type="java.lang.String">
</property>
<subclass name="HourlyEmployee" discriminator-value="HE">
<property name="rate"></property>
</subclass>
<subclass name="SalariedEmployee" discriminator-value="SE">
<property name="salay"></property>
</subclass>
</class>
</hibernate-mapping>
hibernate.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/test1?useUnicode=true&characterEncoding=UTF-8</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password"></property>
<property name="hibernate.show_sql">true</property>
<property name="hibernate.format_sql">true</property>
<mapping resource="com/hibernate/entity/Employee.hbm.xml" />
</session-factory>
</hibernate-configuration>
2.使用注解的方式配置
员工类:
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "employee_type")
public class Employee {
private Integer id;
private String name;
@Id
@GeneratedValue(generator = "my_increment")
@GenericGenerator(name = "my_increment", strategy = "native")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
时薪员工类:
@Entity
@DiscriminatorValue(value = "HE")
public class HourlyEmployee extends Employee {
private double rate;
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
@Override
public String toString() {
return "HourlyEmployee [rate=" + rate + ", getId()=" + getId() + ", toString()=" + super.toString()
+ ", getName()=" + getName() + "]";
}
}
月薪员工类:
@Entity
@DiscriminatorValue(value = "SE")
public class SalariedEmployee extends Employee {
private double salay;
@Column(name = "salary")
public double getSalay() {
return salay;
}
public void setSalay(double salay) {
this.salay = salay;
}
@Override
public String toString() {
return "SalariedEmployee [salay=" + salay + ", toString()=" + super.toString() + "]";
}
}
hibernate.cfg.xml:
@Entity
@DiscriminatorValue(value = "SE")
public class SalariedEmployee extends Employee {
private double salay;
@Column(name = "salary")
public double getSalay() {
return salay;
}
public void setSalay(double salay) {
this.salay = salay;
}
@Override
public String toString() {
return "SalariedEmployee [salay=" + salay + ", toString()=" + super.toString() + "]";
}
}
三:每个类对应一个表(Table per class)
父类,子类都分别对应一张表,父类中包含共有的字段,子类用外键参照关系来表示继承关系。
数据表结构:
持久化类,数据库文件,映射表之间的关系:
加粗样式
1.使用xml的方式进行配置
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.hibernate.entity">
<class name="Employee" table="employee1">
<id name="id" type="int">
<column name="id"></column>
<generator class="native"></generator>
</id>
<property name="name"></property>
<joined-subclass name="HourlyEmployee"
table="hourly_employee1">
<key column="id"></key>
<property name="rate"></property>
</joined-subclass>
<joined-subclass name="SalariedEmployee"
table="salaried_employee1">
<key column="id"></key>
<property name="salay" column="salary"></property>
</joined-subclass>
</class>
</hibernate-mapping>
2.使用注解的方式配置
员工类:
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Employee {
private Integer id;
private String name;
@Id
@GeneratedValue(generator = "my_increment")
@GenericGenerator(name = "my_increment", strategy = "native")
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
时薪员工类:
@Entity
@Table(name="hourly_employee1")
@PrimaryKeyJoinColumn(name="id")
public class HourlyEmployee extends Employee {
private double rate;
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
@Override
public String toString() {
return "HourlyEmployee [rate=" + rate + ", getId()=" + getId() + ", toString()=" + super.toString()
+ ", getName()=" + getName() + "]";
}
}
月薪员工类:
@Entity
@Table(name="salaried_employee1")
@PrimaryKeyJoinColumn(name="id")
public class SalariedEmployee extends Employee {
private double salay;
@Column(name = "salary")
public double getSalay() {
return salay;
}
public void setSalay(double salay) {
this.salay = salay;
}
@Override
public String toString() {
return "SalariedEmployee [salay=" + salay + ", toString()=" + super.toString() + "]";
}
}