hibernate entity 继承投射策略与Mapped SupperClass

JPA实体继承实体的映射策略

 

三种:SINGLE_TABLE(默认的)、TABLE_PER_CLASS、JOINED

 

SINGLE_TABLE: 父子类Entity字段写入同一张表

 

@Entity  
@Table(name = "EMP")  
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)  
@DiscriminatorColumn(name = "emp_type")  
public class Employee implements Serializable {  
  
    private static final long serialVersionUID = -7674269980281525370L;  
      
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    protected Integer empId;  
      
    @Column  
    protected String name;  
  
    // getter/setter方法  
      
}  

@Entity  
@DiscriminatorValue("FT")  
public class FullTimeEmployee extends Employee {  

    @Column  
    private Double salary;  
    // getter/setter方法  
      
}

@Entity  
@DiscriminatorValue("PT")  
public class PartTimeEmployee extends Employee { 

    @Column(name = "hourly_wage")  
    private Float hourlyWage;  
  
    // getter/setter方法  
  
} 

 结论: 只会生成一个表,包含了字段emp_type、empId、name、salary、hourly_wage。当保存FullTimeEmployee时,emp_type的值为“FT”, 当保存PartTimeEmployee时,emp_type的值为“PT”。

 

注:DiscriminatorColumn可对应表中的某一个列(emp_type)来区别记录是由那个子类生成。

 

 

 缺点:子类字段对应的列必须允许null.

 

TABLE_PER_CLASS : 父类子类各自生成一张表,子类只继承父类主键作为自己的主键,不继承其他属性。且子类插入数据与父类无关。

 

 

 

@Entity  
@Table(name = "EMP")  
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)  
public class Employee implements Serializable {  
  
    private static final long serialVersionUID = -7674269980281525370L;  
      
    @Id  
    @GeneratedValue(strategy = GenerationType.TABLE)  
    protected Integer empId;  
      
    @Column  
    protected String name;  
  
    // getter/setter方法  
      
}  
  
@Entity  
@Table(name = "FT_EMP")  
public class FullTimeEmployee extends Employee {  
  
    private static final long serialVersionUID = 9115429216382631425L;  
  
    @Column  
    private Double salary;  
  
    // getter/setter方法  
      
}  
@Entity  
@Table(name = "PT_EMP")  
public class PartTimeEmployee extends Employee {  
  
    private static final long serialVersionUID = -6122347374515830424L;  
  
    @Column(name = "hourly_wage")  
    private Float hourlyWage;  
  
    // getter/setter方法  
  
} 

 

 

结论: 这会映射成三个具体的表,分别是,Employee对应EMP表,字段包括empId、name;FullTimeEmployee对应FT_EMP表,字段包括empId、salary;PartTimeEmployee对应PT_EMP表,字段包括empId、hourly_wage。其中,表FT_EMP和PT_EMP中的empId和EMP表的empId没有任何关系。子类实体每保存一条数据,EMP表中不会插入记录。

 

注意:

1 table_per_class的表生成策略,只有在抽象类不会在其他实体的代码中被引用的时候才适用。

如:

@Entity  
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)  //报错,无法运行,若改为JOINED策略才可
public abstract class Human implements Serializable {  
    private static final long serialVersionUID = 1856374544815477685L;  
        //..........................................  
}  

@Entity  
@Table(name="EMPLOYEE_INFO")  
public class Employee extends Human {  
     //...............................  
} 

@Entity  
public class Award implements Serializable {  
    @ManyToOne  
    private Human publisher;  
}  

2 主键的生成策略不能使用GenerationType.AUTO或GenerationType.IDENTITY,否则会出现异常:

org.hibernate.MappingException: Cannot use identity column key generation with <union-subclass> mapping for: com.mikan.PartTimeEmployee

因为TABLE_PER_CLASS策略每个表都是单独的,没有并且各表的主键没有任何关系,所以不能使用GenerationType.AUTO或GenerationType.IDENTITY主键生成策略,可以使用GenerationType.TABLE。

 

JOINED: 子类父类各自生成表,子类只继承父类的主键作为自己的主键,父类对应表的外键。子类插入数据与父类有关

 

 

@Entity  
@Table(name = "EMP")  
@Inheritance(strategy = InheritanceType.JOINED)  
public class Employee implements Serializable {  
  
    private static final long serialVersionUID = -7674269980281525370L;  
      
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    protected Integer empId;  
      
    @Column  
    protected String name;  
  
    // getter/setter方法  
      
}  
  
@Entity  
@Table(name = "FT_EMP")  
public class FullTimeEmployee extends Employee {  
  
    private static final long serialVersionUID = 9115429216382631425L;  
  
    @Column  
    private Double salary;  
  
    // getter/setter方法  
      
} 
@Entity  
@Table(name = "PT_EMP")  
public class PartTimeEmployee extends Employee {  
  
    private static final long serialVersionUID = -6122347374515830424L;  
  
    @Column(name = "hourly_wage")  
    private Float hourlyWage;  
  
    // getter/setter方法  
  
}  

 

 

结论: 这会映射成三个具体的表,分别是,Employee对应EMP表,字段包括empId、name;FullTimeEmployee对应FT_EMP表,字段包括empId、salary;PartTimeEmployee对应PT_EMP表,字段包括empId、hourly_wage。其中,表FT_EMP和PT_EMP中的empId作为表EMP的外键,同是它也是主键。默认情况下,使用超类的主键作为子类的主键和外键。当然,[email protected]�称,如FullTimeEmployee使用@PrimaryKeyJoinColumn(name = "FT_EMPID")注解,那么该子类实体的字段为FT_EMPID、name,FT_EMPID作为表FT_TIME的主键,同时它也是EMP表的外键。

子类实体每保存一条数据,会在EMP表中插入一条记录,如FT_EMP表插入一条数据,会先在EMP表中插入name,并生成empId,再在FT_EMP表中插入empId和salary。PT_EMP同理。
不管超类是抽象类还是具体类,都会生成对应的表。

 

Mapped SupperClass:父类不对应表,子类继承父类的所有属性生成自己的表。且不能对父类进行查询等操作(因为不对应表)

如:

@MappedSuperclass 
 public class Employee { 
    @Id 
    @GeneratedValue 
    private Long id; 
    private String name; 
    private String depart; 

    // Getters and Setters 
 
 }
 @Entity 
 public class Manager extends Employee { 
     private String office; 
     private String car; 

   // Getters and Setters 
 }

 结论:生成子类对应的表结构:

 CREATE TABLE `manager` ( 

  `ID` bigint(20) NOT NULL, 

  `OFFICE` varchar(255) default NULL, 

  `CAR` varchar(255) default NULL, 

  `DEPART` varchar(255) default NULL, 

  `NAME` varchar(255) default NULL, 

  PRIMARY KEY  (`ID`) 

 

 ) ENGINE=InnoDB DEFAULT CHARSET=latin1;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hibernate 实体类中常用的注解如下: 1. @Entity:表明该类是一个实体类,用于与数据库中的表相映射。 2. @Table:用于指定实体类与数据库中哪张表相映射。 3. @Id:用于指定实体类中的主键属性。 4. @GeneratedValue:用于指定主键生成策略,常用的生成策略有 AUTO、IDENTITY、SEQUENCE 和 TABLE。 5. @Column:用于指定实体类属性与数据库表中哪个列相映射。 6. @Transient:用于标注实体类中不需要持久化到数据库中的属性。 7. @Temporal:用于指定实体类属性与数据库表中的日期时间类型相映射。 8. @OneToMany:用于指定实体类之间的一对多关系。 9. @ManyToOne:用于指定实体类之间的多对一关系。 10. @ManyToMany:用于指定实体类之间的多对多关系。 11. @JoinTable:用于指定多对多关系中的关联表。 12. @JoinColumn:用于指定实体类之间的关联属性。 13. @OrderBy:用于指定查询结果集的排序方式。 14. @NamedQuery:用于定义命名查询。 15. @NamedNativeQuery:用于定义本地 SQL 命名查询。 16. @NamedStoredProcedureQuery:用于定义存储过程命名查询。 17. @SqlResultSetMapping:用于定义查询结果集与实体类之间的映射关系。 18. @Version:用于指定实体类中的乐观锁版本属性。 以上是 Hibernate 实体类中常用的注解,不同的注解在实体类中的作用也不同。需要根据具体的业务需求来选择合适的注解进行使用。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值