Hibernate实体对象继承策略

时间:2021-07-06 00:59:04

Hibernate继承策略总共同拥有三种,一种是共用一张表;一种是每一个类一张表,表里面储存子类的信息和父类的信息;另一种是通过表连接的方式。每一个类都有一张表,可是子类相应的表仅仅保存自己的信息,父类相应的表保存父类的信息。它们之间通过子类表和父类表的关联来获取全部的信息。

第一种方式,即共用一张表:

  1. @Entity
  2. @Inheritance(strategy=InheritanceType.SINGLE_TABLE)
  3. @DiscriminatorColumn(name="discriminator", discriminatorType=DiscriminatorType.STRING)//表示区分不同的对象的字段名
  4. @DiscriminatorValue("person")//用来表示该对象是何种对象的,即区分器
  5. public class Parent {
  6. private int id;
  7. private String name;
  8. @Id
  9. @GeneratedValue
  10. public int getId() {
  11. return id;
  12. }
  13. public void setId(int id) {
  14. this.id = id;
  15. }
  16. public String getName() {
  17. return name;
  18. }
  19. public void setName(String name) {
  20. this.name = name;
  21. }
  22. }
  23. @Entity
  24. @DiscriminatorValue("child1")
  25. public class Child1 extends Parent {
  26. private String email;
  27. public String getEmail() {
  28. return title;
  29. }
  30. public void setEmail(String email) {
  31. this.email = email;
  32. }
  33. }
  34. @Entity
  35. @DiscriminatorValue("child2")
  36. public class Child2 extends Parent {
  37. private String address;
  38. public String getAddress() {
  39. return score;
  40. }
  41. public void setAddress(String address) {
  42. this.address = address;
  43. }
  44. }

这样的情况父类和全部子类的全部信息都保存在同一张表里面,通过我们指定的@DiscriminatorColumn相应的@DiscriminatorValue来差别不同的类。 当没有指定@DiscriminatorValue的时候将使用全类名来作为DiscriminatorValue。

另外一种策略是每一个类一张表,保存全部信息:

  1. @Entity
  2. @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
  3. @TableGenerator(        //一个类一张表。最重要的是要保证它们的id由一个生成器产生,@TableGenerator就是为了控制这个的
  4. name="t_gen",
  5. table="t_gen_table",
  6. pkColumnName="t_pk",
  7. valueColumnName="t_value",
  8. pkColumnValue="person_pk",
  9. ,
  10. )
  11. public class Parent {
  12. private int id;
  13. private String name;
  14. @Id
  15. @GeneratedValue(generator="t_gen", strategy=GenerationType.TABLE)//这个就是用表生成器生成的。用同一个生成器就能够控制它们的id不反复
  16. public int getId() {
  17. return id;
  18. }
  19. public void setId(int id) {
  20. this.id = id;
  21. }
  22. public String getName() {
  23. return name;
  24. }
  25. public void setName(String name) {
  26. this.name = name;
  27. }
  28. }
  29. @Entity
  30. public class Child2 extends Parent {
  31. private String address;
  32. public String getAddress() {
  33. return score;
  34. }
  35. public void setAddress(String address) {
  36. this.address = address;
  37. }
  38. }
  39. @Entity
  40. public class Child1 extends Parent {
  41. private String email;
  42. public String getEmail() {
  43. return title;
  44. }
  45. public void setEmail(String email) {
  46. this.email = email;
  47. }
  48. }

弟三种方式是採用表连接的方式:

  1. @Entity
  2. @Inheritance(strategy=InheritanceType.JOINED)
  3. public class Parent {
  4. private int id;
  5. private String name;
  6. @Id
  7. @GeneratedValue
  8. public int getId() {
  9. return id;
  10. }
  11. public void setId(int id) {
  12. this.id = id;
  13. }
  14. public String getName() {
  15. return name;
  16. }
  17. public void setName(String name) {
  18. this.name = name;
  19. }
  20. }
  21. @Entity
  22. public class Child2 extends Parent {
  23. private String address;
  24. public String getAddress() {
  25. return score;
  26. }
  27. public void setAddress(String address) {
  28. this.address = address;
  29. }
  30. }
  31. @Entity
  32. public class Child1 extends Parent {
  33. private String email;
  34. public String getEmail() {
  35. return title;
  36. }
  37. public void setEmail(String email) {
  38. this.email = email;
  39. }
  40. }

採用表连接的情况,还是每一个类拥有自己的一张表,仅仅是子类相应的表仅仅保存子类的信息。其父类的信息由父类的表保存。

当须要获取子类的完整信息时通过表连接的方式连接子类的表和父类的表获取相应信息。

能够在子类的表上标注@PrimaryKeyJoinColumn(name="foreignKeyName")指明子类表相对于父类表外键的名称。