ch03 继承关系映射
如何建表,保持Java中的父子类继承关系–映射起作用
范例:
一、每个具体类对应一张表 1.建表具体类,即子类,
如父类不需要持久化,那么不为父类建表
HourlyEmployee
| id | name | rate |
|---|---|---|
SalaryEmployee
| id | name | salary |
|---|---|---|
子类较多、公共属性较多时每张表会存在很多重复字段
这种方式相当于多个单实体映射,未体现多态
3.映射文件每个具体类建一个映射文件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Q9fcUihc-1646566955992)(C:Users86183AppDataRoamingTyporatypora-user-imagesimage-20220228201541338.png)]
4.使用注解具体类照常
@Entity
@Table(name = "hourly_emloyee")
public class HourlyEmployee extends Employee {
@Column(name = "rate")
private double rate;
}
未建表的父类添加@MapperedSuperClass
@MappedSuperclass
public class Employee {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
//属性名和表中字段名相同时可以省略column注解,映射文件的column元素也是同样道理
private String name;
}
二、每个类层次对应一张表
1.建表
它们都属于一类,用一张表来表示,添加一个字段作为区分标志
employee
| id | name | employee_type | rate | salary |
|---|---|---|---|---|
支持**多态查询,**就是从数据库中检索父类对象时,同时包含所有子类的对象
3.映射文件1.discriminator:区分标志,不在实体类中出现,只在表中出现,
2.subclass:映射子类
必须紧跟id元素
2.如果 父类本身也需要被持久化,可以在元素中设置 discriminator-value 属性的值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qU0kfqL6-1646566955993)(C:Users86183AppDataRoamingTyporatypora-user-imagesimage-20220228203043981.png)]
4.多态查询一次查询可以查出所有子类对象
// 多态查询--通过一次查询能够得到所有子类的对象,是哪个子类就映射为那个子类对象
public static void findEmployee() {
// 1.获取Session对象
Session session = HibernateUtil.openSession();
// 2.创建查询对象,使用hql
String queryHql = "from Employee ";
Query query = session.createQuery(queryHql);
// 3.执行查询
List list = query.list();// 包含多条--list;唯一--
System.out.println(list);
}
5.使用注解
5.1父类
@Entity
@Table(name="employee")
//继承关系的生成策略
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)//总共一张表
//映射额外字段
@DiscriminatorColumn(name="employee_type")
public class Employee {
@Id
@GeneratedValue(strategy=GenerationType.IDENTI TY)
private Integer id;
private String name;
}
5.2子类
@Entity
@DiscriminatorValue(value="HE")
public class HourlyEmployee extends Employee{
private double rate;
}
注意:
只有父类上标注@Table,因为只有这一个表注意区分标志:父类标注字段名,子类标注字段值 三、每个类对应一张表 1.建表
employee
| id | name |
|---|---|
hourly_employee
| id | rate |
|---|---|
salary_employee
| id | salary |
|---|---|
一个映射文件管理三张表
(1)joined-subclass:标识子类
(2)key:子类的主键
3.使用注解@Entity、@Table都有
3.1父类:指定继承关系的生成策略。
@Inheritance(strategy=InheritanceType.JOINED)3.2子类:
指定子类对应表的主键列。
@PrimaryKeyJoinColumn(name="EMPLOYEEID")
既是主键又是外键
不涉及生成策略
四、三种方式的对比1.实体类一模一样,数据库表不同,映射文件不同
| 关系数据模型的复杂度 | 查询性能 | DB的可维护性 | 是否支持多态查询 | |
|---|---|---|---|---|
| 每个具体类一张表 | 每个具体类中包含重复字段 | 如果查父类,就得查所有具体子类的表 | 若父类属性发生变化,须修改所有子类对应的表 | × |
| 一个大类一张表 | 优:只需创建一个表 缺:表中需额外引入区分子类类型的字段 | 好 | 只需修改一张表 | √ |
| 一个类一张表 | 表的数目多,且表之间存在外键参照关系 | 需要连接查询 | 某个类属性发生变化,只需修改该类对应的表 | √ |



