1.整个类层次对应一个表的映射策略
整个类层次对应一个表的映射策略是Hibernate继承映射默认的映射策略,在这种映射策略下,多种类都存储在一个数据表中,这个数据表包含很多列,这些数据列是整个类层次中所有实体的全部属性的总和。
整个类层次中的所有实体都存放在一个数据表中,那么该如何分表一条记录到底属于哪个实体呢?为该表额外增加一列,使用该列来区分每行记录到底是哪个类的实例—这个列被称为辨别者列。
@DiscriminatorColumn来配置辨别者列,包括指定辨别者列的名称、类型等信息。
使用@DiscriminatorColumn修饰整棵继承树的根父类。
使用这种映射策略时还需要使用@DiscriminatorValue来修饰每个子类,使用该注解时只需指定一个value属性,该value属性值指定不同实体在辨别者列上的值,而Hibernate就是根据该辨别者列上的值来区别各记录属于哪个实体的。
使用整个类层次对应一个表的继承映射策略时,其类中增加的属性映射的字段都不可有非空约束。
2.连接子类的映射策略
如果需要在继承映射中采用这种映射策略,必须在继承树的根类中使用@Inheritance指定映射策略。
使用@Inheritance时必须指定strategy属性,该属性支持如下三个值:
- InheritanceType.SINGLE_TABLE:整个类层次对应一个表的映射策略,这是默认值。
- InheritanceType.JOINED:连接子类的映射策略。
- InheritanceType.TABLE_PER_CLASS:每个具体类对应一个表的映射策略。
采用这种映射策略时,父类实体保存在父类表里,而子类实体则由父类表和子类表共同存储。因为子类实体也是一个特殊的父类实体,因此必然也包含了父类实体的属性,于是将子类与父类共有的属性保存在父类表中,而子类增加的属性则保存在子类表中。
在这种映射策略下,无须使用辨别者列,只要在继承树的根实体类上使用@Inheritance修饰,并为该注解指定strategy=InheritanceType.JOINED。
在这种映射策略下,其子类几乎不需要做任何修改,不需要增加任何和继承有关的注解。
在这种映射策略下,子类增加的属性已经可以增加非空约束了。因为子类的属性和父类没有保存在同一个表中,所以子类的属性也可以增加非空约束。
3.每个具体类对应一个表的映射策略
子类增加的属性也可以有非空约束,即父类实例的数据保存在父表中,而子类实例的数据则保存在子表中。
在这种映射策略下,子类表的字段比父类表的字段要多,因为子类表的字段等于父类属性加子类增加属性的总和。
采用射中映射策略时,不能使用GenerationType.IDENTITY、GenerationType.AUTO这两种主键生成策略。
采用这种映射策略,开发者必须在继承树的根类中使用@Inheritance修饰,指定strategy=InheritanceType.TABLE_PER_CLASS属性。