Hibernate/JPA中的继承映射

来源:互联网 发布:js input 选中事件 编辑:程序博客网 时间:2024/06/06 10:02

Hibernate的继承映射包含了三种不同的策略:
 •每簇类使用一个表;
•每个子类一个表;
•每个具体内一个表(有限制)。
 
假设我们有四个类Animal,Dog,Cat,其代码如下:
文件名:Animal.java
 

class Animal {
    private String identifier;
    private String name;
    private String category;
    // setter and getter
}
 

文件名:Dog.java
 

class Dog extends Animal {
    private String
    // setter and getter
}
 

文件名:Cat.java
 

class Cat extends Animal {
    private String
    // setter and getter
}
 
 
 •每簇类使用一个表

       使用每簇类使用一个表的策略时,有一个限制就时子类不能有NOT NULL,映射文件为:
       文件名:Animal.hbm.xml
 

       <class name="Animal" table="TB_ANIMAL">
          <id name="identifier" type="string" column="IDENTIFIER">
             <generator class="uuid.hex"/>
          </id>
          <discriminator column="ANIMAL_TYPE" type="string"/>
          <property name="name" column="NAME" type="string"/>
         
          <subclass name="Dog" discriminator-value="DOG">
            
          </subclass>
          <subclass name="Cat" discriminator-value="CAT">
            
          </subclass>
       </class>
 
 
 •每个子类一个表

       使用每个子类一个表的策略时,可以使用一个映射文件实现,也可以分成多个映射文件来实现。每个子类一个映射文件的情况:
       文件名:Animal.hbm.xml
 

       <class name="Animal" table="ANIMAL">
          <id name="identifier" column="IDENTIFIER" type="string">
             <generator class="uuid.hex"/>
          </id>
          <property >
       </class>
       文件名:Dog.hbm.xml
       <joined-subclass name="Dog" table="DOG" extends="Animal">
          <key column="DOG_ID"/>
         
       </joined-subclass>
       文件名:Cat.hbm.xml
       <joined-subclass name="Cat" table="CAT" extends="Cat">
          <key column="CAT_ID"/>
         
       </joined-subclass>
 

       每个子类一个表的策略实际上一种one-to-one的映射。
 •每个具体内一个表(有限制)

       使用每个具体内一个表(有限制)策略时,每一个子类的映射文件将要包含所有父类中的属性,映射文件:
       文件名:Dog.hbm.xml
 

       <class name="Dog" table="DOG">
          <id name="identifier" column="IDENTIFIER" type="string">
             <generator class="uuid.hex"/>
          </id>
          <property name="name" column="NAME" type="string"/>
         
       </class>
       文件名:Cat.hbm.xml
       <class name="Cat" table="CAT">
          <id name="identifier" column="IDENTIFIER" type="string">
             <generator class="uuid.hex"/>
          </id>
          <property name="name" column="NAME" type="string"/>
         
       </class>

 
 
 
JPA中的实体层次设计
 


这部分的内容基本与Hibernate一致.JPA同样支持3种类型的继承形式:
 
1.Single Table Strategy ,单表策略,一张表包含基类与子类的所有数据,很多情况下都是采用这样的冗余设计,通过一个discriminator来区分
 
2.Table Per Class Strategy ,每个子类对应一张表,每张表都拥有基类的属性
 
3.Join Strategy ,仍然是每个子类对应一张表,但此表中不包含基类的属性,仅仅是此子类的扩展属性,共享基类的属性
 
 
 
以一个例子来说明3种情况:
 
一.单表策略
 
比如Pet作为基类,Cat和Dog继承此类并拥有自己的扩展属性,如:
 
package com.denny_blue.ejb3.inheritance;
 
import java.io.Serializable;
 
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
 
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "animal_type", discriminatorType = DiscriminatorType.STRING)
public class Pet implements Serializable {
 private int id;
 
 private String name;
 
 private double weight;
 
 public Pet() {
 }
 
 @Id
 @GeneratedValue(strategy = GenerationType.AUTO)
 public int getId() {
  return id;
 }
 
 public void setId(int id) {
  this.id = id;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
  this.name = name;
 }
 
 public double getWeight() {
  return weight;
 }
 
 public void setWeight(double weight) {
  this.weight = weight;
 }
 
}
 
Pet类值的注意的就是通过@Inheritance(strategy = InheritanceType.SINGLE_TABLE)确定采用单表策略,通过@DiscriminatorColumn确定了标志值的字段和类型,我想熟悉hibernate的朋友对这些都应该很熟悉.然后是两个子类:
 
//Cat.java
 
package com.denny_blue.ejb3.inheritance;
 
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
 
@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING)
@DiscriminatorValue("cat")
public class Cat extends Pet {
 private String HairBall;
 
 public String getHairBall() {
  return HairBall;
 }
 
 public void setHairBall(String hairBall) {
  HairBall = hairBall;
 }
 
}
 
//Dog.java
 
package com.denny_blue.ejb3.inheritance;
 
import javax.persistence.DiscriminatorColumn;
import javax.persistence.DiscriminatorType;
import javax.persistence.DiscriminatorValue;
import javax.persistence.Entity;
import javax.persistence.Inheritance;
import javax.persistence.InheritanceType;
 
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING)
@DiscriminatorValue("dog")
public class Dog extends Pet {
 private String trick;
 
 public String getTrick() {
  return trick;
 }
 
 public void setTrick(String trick) {
  this.trick = trick;
 }
 
}
 
两个子类最值的关注的就是@DiscriminatorValue注释,比如Cat的此值为cat,意味着当Cat类型的Entity存入数据库时,JPA将自动把cat的值赋给animal_type字段,Dog的值则为dog,由此就可以在同一张表中区分开两个不同的子类.
 
 
 
二.Table per Class
 
采用Table Per Class策略的话,每个子类都将单独建表,并且都独立拥有基类中的所有属性,互相之间不共享,在我们的例子中所要进行的修改很小,像这样:
 
//基类
 
@Entity
@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class Pet implements Serializable {
 private int id;
 
 private String name;
 
 private double weight;
 
........
 
//子类:不需要任何设置
 
@Entity
public class Dog extends Pet {
 private String trick;
 
  .......
 
  .......
 
 
 
三.Join策略
 
每个子类同样独立建表,基类也独立建表,只不过所有的子类的表中只有扩展属性,他们共享基类的表,在我们的例子中修改下即可:
 
//基类
 
@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class Pet implements Serializable {
 private int id;
 
 private String name;
 
 private double weight;
 
  ........
 
//子类
 
@Entity
 
@Inheritance(strategy = InheritanceType.JOINED)
public class Dog extends Pet {
 private String trick;

 

另外下面这篇也不错,可以去看看:

http://www.blogjava.net/zhaochengming/articles/136193.html

原创粉丝点击