jpa中的继承层次结构

本文介绍了JPA中处理继承层次结构的四种方法:每个具体类一张表、每个子类一张表、联合表以及每个类层次结构一张表,并详细解析了每种策略的特点及其在JPA和Hibernate中的实现。

表示一个继承层次结构的有4中方法

1.每个带有隐式多态的具体类一张表

2.每个子类一张表

3.每个带有联合一张表

4.每个类层次结构一张表


1.每个带有隐式多台的具体类一张表

    1.对于父类的属性,子类全部都在自己表中放至相应的字段,即在表中加上父表的字段,父类无单独的一张表

    2.父类上加入@mappedSupperClass,然后子类就会继承父类,而且子类也可以改写父类的字段属性
名.eg.@AttributeOverride (name = "owner", column = @Column(name = "CC_OWNER" , nullable = false))

       3.对于这种继承映射:父类把属性(field)和映射(mapping) 复制到子类【A class designated with the MappedSuperclass annotation can be mapped in the same way as an entity except that the mappings will apply only to its subclasses since no table exists for the mapped superclass itself】,在数据库中,关联通常被表示为外键关系,如果子类全部映射到不同的表【标识符属性映射不能被共享】,对于基类的多态关联就无法表示为一个简单的外键关系,此中继承映射很少被使用

@MappedSuperclass
public class BillingDetails {
     
     private String owner;

     public String getOwner() {
            return owner;
     }

     public void setOwner(String owner) {
            this. owner = owner;
     }
     

}


子类:
@Entity
@Table(name="billing" )
@AttributeOverride(name = "owner" , column = @Column (name = "CC_OWNER", nullable = false ))
@GenericGenerator(name="native" , strategy="increment" )
public class CreditCard extends BillingDetails {
   @Id
   @GeneratedValue(generator= "native")
     private long id;
     
     private String number;

     public long getId() {
            return id;
     }

     public void setId( long id) {this. id = id;
     }

     public String getNumber() {
            return number;
     }

     public void setNumber(String number) {
            this. number = number;
     }

}

     

2.每个子类一张表


此映射的思想为:通过外键连接,为类层次结构中每一个类创建一张表,即使抽象类或者接口也是,他们彼此通过主外键连接,公用的属性放在父类,通过外键获取[缺点:无法为复杂的类层次结构所用,因为要跨越外键来建立连接]相当于hibernate映射文件中的<joined-subclass>
2.在子类中,如果子类表的主键与基类的主键有着相同的名称,则不需要指定连接列,即
@PrimaryKeyJoinColumn,否则必须指定@PrimaryKeyJoinColumn(name="foreign_key") 

3.继承策略为InheritanceType.JOINED,在父类中要显示指出,通过@Inheritance(strategy=InheritanceType.JOINED)

父类:
@Entity
@Table(name="billing" )
@Inheritance(strategy=InheritanceType.JOINED)
@GenericGenerator(name="native" , strategy="increment" )
public abstract class BillingDetails {
     @Id
     @GeneratedValue(generator= "native")
     private long id;
   
     private String owner;

     public String getOwner() {
            return owner;
     }

     public void setOwner(String owner) {
            this. owner = owner;
     }
     
     public long getId() {
            return id;
     }
     
     public void setId( long id) {
            this. id = id;
     }

}

继承子类:
@Entity
@Table(name="credit" )
public class CreditCard extends BillingDetails {
     private String name;
   
     public String getName() {
            return name;
     }

     public void setName(String name) {
            this. name = name;
     }

}


 3.每个带有联合一张表


    1.超类声明为抽象类或者接口,此目的为避免实例化基类,如果基类被实例化那么基类就需要单独的一张表了

     2.数据库标识符映射被该映射层次的子类所共享给,所以要把子类的数据库标识符移到超类中,子类中删除数据库标识符属性(如果不移到基类中,则相当于了@mappedSupperClass,此时数据库标识符不能被共享)

    3.映射策略为InheritanceType.TABLE_PER_CLASS,声明方式为在父类中加入@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)

  4.TABLE_PER_CLASS策略在JPA标准中被标记为可选,并非所有的JPA都实现它,它的实现是由供应商决定的,在HIBERNATE中,相当于<union-subclass></union-subclass>


父类:
@Entity
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@GenericGenerator(name="native" , strategy="increment" )
public abstract class BillingDetails {
     @Id
     @GeneratedValue(generator= "native")
     private long id;
   
     private String owner;

     public String getOwner() {
            return owner;
     }

     public void setOwner(String owner) {
            this. owner = owner;
     }
     
     public long getId() {
            return id;
     }
     
     public void setId( long id) {
            this. id = id;
     }

}


子类:
@Entity
@Table(name="billing" )
public class CreditCard extends BillingDetails {
     private String number;

     public String getNumber() {
            return number;
     }

     public void setNumber(String number) {
            this. number = number;
     }

}

4.每个类层次结构一张表

     整个类层次结构都可以被映射到一张表,这张表把所有类的属性都映射到字段中,特定行表示的具体子类由类型辨别标识列进行识别

      1.映射访问策略为InheritanceType.SINGLE_TABLE,通过在父类加入

@Inheritance(strategy=InheritanceType.SINGLE_TABLE)实现
  2.映射到一张表,则@table应该加在父类上,因为如果加在子类上,那么每个子类都需要加上@table,那时就达不到映射到一张表的目的
 
   3.父类上需要指定辨别标识列,
@DiscriminatorColumn(name="discriminator" , discriminatorType=DiscriminatorType.STRING ),如果不指明的话,那么默认的列名为DTYPE,类型默认为字符串。

   4.子类中通过@DiscriminatorValue ("CC")属性指定标识列的值,如果没有指定@DiscriminatorValue,则默认为子类实例名


@Entity
@Table(name="billing" )
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="discriminator" , discriminatorType=DiscriminatorType.STRING )
@GenericGenerator(name="native" , strategy="increment" )
public abstract class BillingDetails {
     @Id
     @GeneratedValue(generator= "native")
     private long id;
   
     private String owner;

     public String getOwner() {
            return owner;
     }

     public void setOwner(String owner) {
            this. owner = owner;
     }
     
     public long getId() {
            return id;
     }
     
     public void setId( long id) {
            this. id = id;
     }

}

子类:
@Entity
@DiscriminatorValue ("CC")
public class CreditCard extends BillingDetails {
     private String number;

     public String getNumber() {
            return number;
     }

     public void setNumber(String number) {
            this. number = number;
     }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值