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

全面研讀 EJB 2.0 (上):CMP 2.0 抽象持久化方案與持久化管理器架構

     編輯:J2EE

EJB 2.0 重大變革概覽

  • 規範擴充 66% (500+ 頁),核心變更集中於 CMP 2.0 全新模型 與 MessageDrivenBean 引入
  • 向下相容:產品必須同時支援 EJB 1.1 CMP 與 2.0 模型 (兩者不相容)

CMP 1.0 痛點回顧

  • Bean 開發者直接宣告持久化欄位 (primitive/Serializable)
  • 可序列化物件 (如 `Address`) 難以對應關聯式資料庫,常序列化為 BLOB
  • 關聯關係 (Bean-Bean、Bean-Dependent) 缺乏標準化映射機制
  • 部署描述符僅有 `` 標記欄位,無法描述複雜物件圖

CMP 2.0 核心創新:抽象持久化方案

持久化管理器

  • 新增部署角色:容器廠商或專業持久化廠商提供
  • 職責:依抽象持久化方案將 Entity Bean 映射至資料庫、實作查詢方法
  • 分離關注點:容器管安全/事務/資源,持久化管理器管 Object-Relational 映射
  • 支援多種資料源:關聯式 DB、物件 DB、ERP (SAP) 等

Bean 類別宣告為 abstract

  • 不直接定義持久化欄位,改以 抽象 getter/setter 定義
  • 方法簽章對應部署描述符 XML 元素
  • 部署時持久化管理器工具產生具體子類別,注入資料存取邏輯
  • 執行期容器使用產生的子類別,而非開發者原始抽象類別

程式碼範例:Employee Entity Bean

public abstract class EmployeeBean implements javax.ejb.EntityBean {
    EntityContext ejbContext;

    // CMP 欄位
    public abstract void setIdentity(int identity);
    public abstract int getIdentity();
    public abstract void setFirstName(String firstName);
    public abstract String getFirstName();
    public abstract void setLastName(String lastName);
    public abstract String getLastName();

    // 關聯欄位 (Dependent Object)
    public abstract void setContactInfo(ContactInfo info);
    public abstract ContactInfo getContactInfo();
}

部署描述符片段

<entity>
  <ejb-name>EmployeeEJB</ejb-name>
  <persistence-type>Container</persistence-type>
  <cmp-field><field-name>identity</field-name></cmp-field>
  <cmp-field><field-name>firstName</field-name></cmp-field>
  <cmp-field><field-name>lastName</field-name></cmp-field>
  ...
</entity>

<dependents>
  <dependent>
    <dependent-class>ContactInfo</dependent-class>
    <dependent-name>ContactInfo</dependent-name>
    <cmp-field>street</cmp-field>
    <cmp-field>city</cmp-field>
    <cmp-field>state</cmp-field>
    <cmp-field>zip</cmp-field>
    <cmp-field>homePhone</cmp-field>
    <cmp-field>workPhone</cmp-field>
    <cmp-field>email</cmp-field>
  </dependent>
</dependents>

<relationships>
  <ejb-relation>
    <ejb-relation-name>Employee-ContactInfo</ejb-relation-name>
    <ejb-relationship-role>
      <ejb-relationship-role-name>employee-has-contactinfo</ejb-relationship-role-name>
      <multiplicity>one</multiplicity>
      <role-source><ejb-name>EmployeeEJB</ejb-name></role-source>
      <cmr-field>
        <cmr-field-name>contactInfo</cmr-field-name>
        <cmr-field-type>ContactInfo</cmr-field-type>
      </cmr-field>
    </ejb-relationship-role>
    <ejb-relationship-role>
      <ejb-relationship-role-name>contactinfo-belongs-to-employee</ejb-relationship-role-name>
      <multiplicity>one</multiplicity>
      <role-source><dependent-name>ContactInfo</dependent-name></role-source>
    </ejb-relationship-role>
  </ejb-relation>
</relationships>

Dependent Object (從屬物件) 關鍵特性

  • 隨 Entity Bean 生命週期建立/銷毀 (級聯刪除)
  • 僅對 Bean 類別可見,不曝露給客戶端 (非 Remote/Local 介面參數/回傳型別)
  • 持久化管理器擴充抽象 Dependent 類別實作運行期持久化邏輯
  • 設計策略:持久化建模 ≠ 業務建模,客戶端透過領域物件 (如 `Address`) 存取資料

對客戶端隱藏 ContactInfo 範例

// Remote 介面曝露領域物件
public interface Employee extends javax.ejb.EJBObject {
    public Address getHomeAddress();
    public void setHomeAddress(Address address);
    // 其他基本欄位...
}

// Bean 實作轉換
public abstract class EmployeeBean implements javax.ejb.EntityBean {
    public Address getHomeAddress() {
        ContactInfo info = getContactInfo();
        Address addr = new Address();
        addr.street = info.getStreet(); addr.city = info.getCity();
        addr.state = info.getState(); addr.zip = info.getZip();
        return addr;
    }
    public void setHomeAddress(Address addr) {
        ContactInfo info = getContactInfo();
        info.setStreet(addr.street); info.setCity(addr.city);
        info.setState(addr.state); info.setZip(addr.zip);
    }
}

關聯多樣性支援

關聯類型Bean 端型別範例
Bean ↔ Dependent (1:1)Dependent 類別型別`setBenefit(Benefit)`
Bean ↔ Dependent (1:N)`Collection` / `Set``setContactInfos(Collection)`
Bean ↔ Bean (1:1)Remote 介面型別`setSpouse(Person)`
Bean ↔ Bean (1:N)`Collection` / `Set``setChildren(Collection)`
Dependent ↔ Dependent同上`Benefit ↔ Salary` (1:1), `Benefit ↔ Investment` (1:N)

未來版本擬支援 `Map`、`List` 回傳型別。

容器與持久化管理器契約

  • 持久化管理器取得事務控制代碼、存取容器管理的連線池
  • 契約尚寬鬆,未來將強化以確保跨容器可攜性
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved