首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

EJB 3.0 實體 Bean 繼承完全指南:三大策略與註解驅動實戰

     編輯:Java 程式設計入門

繼承映射三大策略

EJB 3.0 透過 @Inheritance 註解定義實體繼承映射策略:

策略註解值資料表結構適用場景
單表策略SINGLE_TABLE父/子實體共用一張表,判別欄位區分類型層次淺、欄位少、查詢效能優先
連接表策略JOINED父表存共同欄位,子表存特有欄位,主鍵關聯規範化要求高、子實體差異大
每類一表TABLE_PER_CLASS每個實體類獨立一表,含所有欄位(含繼承)多態查詢少、獨立演化需求強

核心註解詳解

@Inheritance

@Inheritance(
    strategy = InheritanceType.SINGLE_TABLE,
    discriminatorType = DiscriminatorType.STRING,
    discriminatorValue = "PERSON"
)
  • strategy:三種策略之一,預設 SINGLE_TABLE
  • discriminatorType:判別欄位類型(STRING/CHAR/INTEGER)
  • discriminatorValue:當前實體在判別欄的值

@DiscriminatorColumn

@DiscriminatorColumn(
    name = "P_TYPE",
    discriminatorType = DiscriminatorType.STRING,
    length = 10,
    nullable = true
)
  • 僅用於 SINGLE_TABLE 與 JOINED 策略
  • 定義判別欄名稱、類型、長度、可空性

實戰案例:Person → Man / Woman

父實體 Person

@Entity
@Inheritance(strategy = InheritanceType.SINGLE_TABLE, discriminatorType = DiscriminatorType.STRING)
@DiscriminatorColumn(name = "P_TYPE", nullable = true)
@DiscriminatorValue("PERSON")
public class Person implements Serializable {
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;
    private String name;
    private String gender;
    // getter/setter...
}

子實體 Man

@Entity
@DiscriminatorValue("MAN")
public class Man extends Person {
    private String beardStyle; // 男性特有屬性
    // getter/setter...
}

子實體 Woman

@Entity
@DiscriminatorValue("WOMAN")
public class Woman extends Person {
    private String hairStyle; // 女性特有屬性
    // getter/setter...
}

資料庫表結構 (SINGLE_TABLE)

CREATE TABLE PERSON (
    ID INT PRIMARY KEY,
    NAME VARCHAR(100),
    GENDER VARCHAR(10),
    BEARD_STYLE VARCHAR(50),  -- Man 專用,Woman 為 NULL
    HAIR_STYLE VARCHAR(50),   -- Woman 專用,Man 為 NULL
    P_TYPE VARCHAR(10) NOT NULL  -- 判別欄:'PERSON'/'MAN'/'WOMAN'
);

測試客戶端

EntityManager em = emf.createEntityManager();
em.getTransaction().begin();

Man man = new Man();
man.setName("Adam");
man.setGender("Male");
man.setBeardStyle("Full");
em.persist(man);

Woman woman = new Woman();
woman.setName("Eve");
woman.setGender("Female");
woman.setHairStyle("Long");
em.persist(woman);

em.getTransaction().commit();
// 查詢驗證
List<Person> all = em.createQuery("SELECT p FROM Person p").getResultList();

策略選擇決策樹

  1. 查詢頻繜涉及多態(FROM Person)且子類欄位少 → SINGLE_TABLE
  2. 嚴格規範化、子類欄位多、存儲空間敏感 → JOINED
  3. 極少多態查詢、各子類獨立演化 → TABLE_PER_CLASS(注意:部分 JPA 提供者支援有限)

最佳實踐提醒

  • 判別欄加索引,提升多態查詢速度
  • 避免過深繼承層次(>3 層),維護成本劇增
  • 組合優於繼承:能用 @Embedded / 關聯關係解決的,盡量不用繼承
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved