实体与实体之间有时候是有一定的关系的,他们中间的大部分字段是相同的,而相同的代码需要我们写两遍,这是我们所不能忍受的,所以就有了继承,抽象出一个公共的父类,将相同的部分放在其中。而我们今天要说的Hibernate 的映射策略,是针对实体与数据表的关系说的。
问题描述
两个系统,他们公用同一个后台。每个系统都有一个菜单类,现在两个菜单类实体的属性基本相同,需要用实体继承来实现。
策略一:单表映射(single)
描述
单表映射,顾名思义,只有一张表。它表示父类和继承它的子类共同使用一张数据表,然后另设一个字段,用来区分不同的实体。
用法演示
父类:
在父类中使用注解@Inheritance来声明这是继承的父类,然后在参数中定义继承的策略:单表继承SINGLE_TABLE。
使用注解@DiscriminatorColumn来生成一个新的字段,用来区别两个不同的子类。参数为字段的名字。
|
|
子类:
在子类中,只需要通过注解@DiscriminatorValue来设置自己对应的用来区分的字段的名字。然后继承父类就行了。
|
|
|
|
最后会生成类似下面的表结构:

策略二:Joined策略
描述
这种策略从字面上来看:加入,加盟。它的意思就是父类和子类都各自生成数据表,但是,父类的数据表中只有公共的字段,子类的数据表中只有扩展的字段。你生成你的字段,我生成我的字段,然后我们合起来就是完整的表了。
用法演示
父类:
父类中只需要通过@Inheritance注解来声明这是父类,然后策略为:JOINED。
|
|
子类:
由于需要对应不同的数据表,而又没有重新定义主键,所以需要使用@PrimaryKeyJoinColumn注解来声明一下主键。
|
|
|
|
策略三:Table per Class策略
描述
这个策略也很好理解:一个类一张表嘛。而这个策略的特点是,每个子类单独创建数据表,并且拥有父类中的所有属性,数据也不会共享。
用法演示
父类:
父类的改动很小,只需要将上面的策略换成:TABLE_PER_CLASS就行了。
|
|
子类:
由于子类生成的表中会包含所有字段,所以子类什么也不需要做。
|
|
|
|
总结
Hibernate为我们解决了实体继承的问题,让我们不必再纠结实体与数据表的关系。但是这三种映射策略并不是什么时候都能使用的,还是需要看实际的项目中是什么样的情况,针对不同的情况使用不同的策略,才能发挥他最强大的功能。