4 继承映射

对于类与类之间的继承关系,hibernate提供了三种映射策略。

InheritanceType.SINGE_TABLE:整个层次对应一张表,默认

InheritanceType.JOINED:连接子类的映射策略

InheritanceType.TABLE_PER_CLASS:每个具体类对应一个表。

1 整个类层次对应一个表

整个类层次对应一个表的映射策略是Hibernate的默认的继承映射策略,在这种策略下,父类、子类同在一个表中。

为了区分记录到底属于哪个实体,在创建表时,会增加额外一列——辨别者列(discriminator)

在Hibernate中使用整个类层次对应一个表时,使用@DiscriminatorColumn修饰正课继承树的根父类

@Entity
// 定义辨别者列的列名为person_type,列类型为字符串
@DiscriminatorColumn(name="person_type" ,
	discriminatorType=DiscriminatorType.STRING)
// 指定Person实体对应的记录在辨别者列的值为"普通人"
@DiscriminatorValue("普通人")
@Table(name="person_inf")
public class Person
{
	// 标识属性
	@Id @Column(name="person_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	private String name;
}

上面的Person类是整个类继承系统的跟雷,因此程序使用@DiscriminatorColumn修饰该持久化类,也使用了@DiscrimininatorValue修饰它。指定了value="普通人“,这意味着当辨别这列的值为普通人时,Hibernate即可识别该条记录为Person实体。

@Entity
// 指定Employee实体对应的记录在辨别者列的值为"员工"
@DiscriminatorValue("员工")
@Table(name="employee_inf")
public class Employee extends Person
{
	// 定义该员工职位的成员变量
	private String title;
	// 定义该员工工资的成员变量
	private double salary;
	// 定义和该员工保持关联的Customer关联实体
	@OneToMany(cascade=CascadeType.ALL
		, mappedBy="employee" , targetEntity=Customer.class)
	private Set<Customer> customers
		= new HashSet<>();
	// 定义和该员工保持关联的Manager关联实体
	@ManyToOne(cascade=CascadeType.ALL
		,targetEntity=Manager.class)
	@JoinColumn(name="manager_id", nullable=true)
	private Manager manager;
}

使用这种策略有一个好处就是无论如何查询,记录都保存在一张表内,无需进行union查询。

2 连接子类的映射策略

这种策略不是默认策略,如果需要使用,必须在继承树的根目录中@Inheritance指定映射策略。

采用这种映射策略时,父类实体保存在父类表中,而自恋实体则由父类表和子类表共同存储。在子类表中仅保存子类增加的属性。


@Entity
// 指定使用连接子类的映射策略
@Inheritance(strategy=InheritanceType.JOINED)
@Table(name="person_inf")
public class Person
{
	// 标识属性
	@Id @Column(name="person_id")
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Integer id;
	private String name;
	private char gender;

在这种映射策略下,子类不需要用任何注解修饰

// 员工类继承了Person类
@Entity
@Table(name="employee_inf")
public class Employee extends Person
{
	// 定义该员工职位的成员变量
	private String title;
	// 定义该员工工资的成员变量
	private double salary;
	// 定义和该员工保持关联的Customer关联实体
	@OneToMany(cascade=CascadeType.ALL
		, mappedBy="employee" , targetEntity=Customer.class)
	private Set<Customer> customers
		= new HashSet<>();
	// 定义和该员工保持关联的Manager关联实体
	@ManyToOne(cascade=CascadeType.ALL
		,targetEntity=Manager.class)
	@JoinColumn(name="manager_id", nullable=true)

使用这种策略时,查询时可能需要跨越多个表,这取决于继承树的深度,如果深度较深,可能导致性能低下。

3 每个具体类对应一个表的映射策略

这种策略父类的实例保存在父表中,子类的实例保存在子表中。在这种情况下,从数据库来看,很难看出存在继承关系,只是多个实体之间的主键值具有某种连续性,因此不能让数据库为各自的表生成主键值

@Entity
// 指定使用每个具体类对应一张表的映射策略
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@Table(name="person_inf")
public class Person
{
	// 标识属性
	@Id @Column(name="person_id")
	// 由于不能使用identity主键生成策略,故此处采用hilo主键生成策略
	@GenericGenerator(name="person_hilo" , strategy="hilo")
	@GeneratedValue(generator="person_hilo")
	private Integer id;
	private String name;
	private char gender;

/ 员工类继承了Person类
@Entity
@Table(name="employee_inf")
public class Employee extends Person
{
	// 定义该员工职位的成员变量
	private String title;
	// 定义该员工工资的成员变量
	private double salary;
	// 定义和该员工保持关联的Customer关联实体
	@OneToMany(cascade=CascadeType.ALL
		, mappedBy="employee" , targetEntity=Customer.class)
	private Set<Customer> customers
		= new HashSet<>();
	// 定义和该员工保持关联的Manager关联实体
	@ManyToOne(cascade=CascadeType.ALL
		,targetEntity=Manager.class)
	@JoinColumn(name="manager_id", nullable=true)
	private Manager manager;










  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值