Hibernate实体对象继承策略

Hibernate的继承策略包括:单表策略、每类一表和表连接策略。单表策略下,所有类的信息存储在一张表中,通过@DiscriminatorColumn和@DiscriminatorValue区分。每类一表策略中,每个类都有独立表,使用@TableGenerator确保ID不重复。表连接策略则让每个类有自己的表,父类信息存于父类表,子类信息存于子类表,通过表连接获取完整信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        Hibernate继承策略总共有三种,一种是共用一张表;一种是每个类一张表,表里面储存子类的信息和父类的信息;还有一种是通过表连接的方式,每个类都有一张表,但是子类对应的表只保存自己的信息,父类对应的表保存父类的信息,它们之间通过子类表和父类表的关联来获取所有的信息。

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

Java代码
 收藏代码
  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.       
  9.     @Id  
  10.     @GeneratedValue  
  11.     public int getId() {  
  12.         return id;  
  13.     }  
  14.     public void setId(int id) {  
  15.         this.id = id;  
  16.     }  
  17.     public String getName() {  
  18.         return name;  
  19.     }  
  20.     public void setName(String name) {  
  21.         this.name = name;  
  22.     }  
  23.   
  24. }  
  25.   
  26. @Entity  
  27. @DiscriminatorValue("child1")  
  28. public class Child1 extends Parent {  
  29.     private String email;  
  30.   
  31.     public String getEmail() {  
  32.         return title;  
  33.     }  
  34.   
  35.     public void setEmail(String email) {  
  36.         this.email = email;  
  37.     }  
  38.   
  39.       
  40. }  
  41.   
  42.   
  43.   
  44. @Entity  
  45. @DiscriminatorValue("child2")  
  46. public class Child2 extends Parent {  
  47.       
  48.     private String address;  
  49.   
  50.     public String getAddress() {  
  51.         return score;  
  52.     }  
  53.   
  54.     public void setAddress(String address) {  
  55.         this.address = address;  
  56.     }  
  57.       
  58. }   

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

 

 

第二种策略是每个类一张表,保存所有信息:

Java代码
 收藏代码
  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.         initialValue=1,  
  10.         allocationSize=1  
  11.         )  
  12. public class Parent {  
  13.     private int id;  
  14.     private String name;  
  15.       
  16.     @Id  
  17.     @GeneratedValue(generator="t_gen", strategy=GenerationType.TABLE)//这个就是用表生成器生成的,用同一个生成器就可以控制它们的id不重复  
  18.     public int getId() {  
  19.         return id;  
  20.     }  
  21.     public void setId(int id) {  
  22.         this.id = id;  
  23.     }  
  24.     public String getName() {  
  25.         return name;  
  26.     }  
  27.     public void setName(String name) {  
  28.         this.name = name;  
  29.     }  
  30.   
  31. }  
  32.   
  33.   
  34. @Entity  
  35. public class Child2 extends Parent {  
  36.       
  37.     private String address;  
  38.   
  39.     public String getAddress() {  
  40.         return score;  
  41.     }  
  42.   
  43.     public void setAddress(String address) {  
  44.         this.address = address;  
  45.     }  
  46.       
  47. }  
  48.   
  49.   
  50. @Entity  
  51. public class Child1 extends Parent {  
  52.     private String email;  
  53.   
  54.     public String getEmail() {  
  55.         return title;  
  56.     }  
  57.   
  58.     public void setEmail(String email) {  
  59.         this.email = email;  
  60.     }  
  61.   
  62.       
  63. }  

 

 

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

Java代码
 收藏代码
  1. @Entity  
  2. @Inheritance(strategy=InheritanceType.JOINED)  
  3.   
  4. public class Parent {  
  5.     private int id;  
  6.     private String name;  
  7.       
  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. }  
  24.   
  25. @Entity  
  26. public class Child2 extends Parent {  
  27.       
  28.     private String address;  
  29.   
  30.     public String getAddress() {  
  31.         return score;  
  32.     }  
  33.   
  34.     public void setAddress(String address) {  
  35.         this.address = address;  
  36.     }  
  37.       
  38. }  
  39.   
  40.   
  41. @Entity  
  42. public class Child1 extends Parent {  
  43.     private String email;  
  44.   
  45.     public String getEmail() {  
  46.         return title;  
  47.     }  
  48.   
  49.     public void setEmail(String email) {  
  50.         this.email = email;  
  51.     }  
  52.   
  53.       
  54. }  

         采用表连接的情况,还是每个类拥有自己的一张表,只是子类对应的表只保存子类的信息,其父类的信息由父类的表保存。当需要获取子类的完整信息时通过表连接的方式连接子类的表和父类的表获取对应信息。可以在子类的表上标注@PrimaryKeyJoinColumn(name="foreignKeyName")指明子类表相对于父类表外键的名称。

课程通过实际项目融入常用开发技术架构,讲授风格独特,提供详细上课日志及答疑,赠送配套的项目架构源码注释详细清晰且达通俗,均能直接在实际项目中应用,正真的物超所值,价格实惠任务作业:综合运用《C#/.Net企业级系统架构设计实战精讲教程》课程所学知识技能设计一个学生成绩管理系统的架构。要求:1.系统基于MVC的三层架构,各层单独建不同的解决方案文件夹。2.采用Model First开发方式,设计架构时只需要设计学生(TbStudent)和课程(TbCourse)。学生必须有的字段是ID、stuName、age;课程必须有的字段是ID、courseName、content。3.数据访问层采用Entity Framework或NHibernate来实现,必须封装对上述的增删改查方法。4.必须依赖接口编程,也就是必须要有数据访问层的接口层、业务逻辑层的接口层等接口层。层层之间必须减少依赖,可以通过简单工厂或抽象工厂。5.至少采用简单工厂、抽象工厂、Spring.Net等技术中的2种来减少层与层之间的依赖等。6.封装出DbSession类,让它拥有所有Dal层实例和SaveChanges方法。7.设计出数据访问层及业务逻辑层主要类的T4模板,以便实体增加时自动生成相应的类。8.现层要设计相关的控制器和视图来验证设计的系统架构代码的正确性,必须含有验证增删改查的方法。9.开发平台一定要是Visual Studio平台,采用C#开发语言,数据库为SQL Server。10.提交整个系统架构的源文件及生成的数据库文件。(注意: 作业需写在优快云博客中,请把作业链接贴在评论区,老师会定期逐个批改~~)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值