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

EJB 實體 Bean 與數據庫持久化實戰:以銀行賬戶為例

     編輯:Java 相關知識

EJB 組件類型選擇

場景推薦組件
簡單邏輯、數據不共享、非業務實體Session Bean + JDBC/SQL
多客戶端共享數據、業務實體建模、需事務管理Entity Bean (CMP/BMP)

Entity Bean 核心契約

Entity Bean 代表持久化業務實體,特徵:

  • 主鍵唯一標識
  • 可被多客戶端共享
  • 容器管理事務(聲明式)
  • 持久化策略:CMP(容器管理)或 BMP(Bean 管理)

數據源與連接池

EJB 容器維護連接池,組件通過 JNDI 邏輯名獲取:

@Resource(name="jdbc/AccountDB")
private DataSource ds;

Connection con = ds.getConnection(); // 從池獲取
// 業務邏輯...
con.close(); // 歸還池

優勢:組件與具體數據庫解耦,支援跨環境部署。

Entity Bean 關鍵回調方法 (BMP 示例)

ejbCreate - 創建實體

public String ejbCreate(String id, String first, String last, double bal)
    throws CreateException {
    if (bal < 0) throw new CreateException("餘額不能為負");
    insertRow(id, first, last, bal); // JDBC INSERT
    this.id = id; this.firstName = first; this.lastName = last; this.balance = bal;
    return id; // 返回主鍵
}

ejbPostCreate - 創建後續操作

對應每個 ejbCreate,通常為空,可調用 getPrimaryKey()。

ejbRemove - 刪除實體

public void ejbRemove() {
    deleteRow(id); // JDBC DELETE
}

ejbLoad / ejbStore - 同步狀態

  • 容器在事務開始前調用 ejbLoad 從 DB 刷新字段
  • 事務提交前調用 ejbStore 將字段寫回 DB
  • 開發者無需在業務方法中手動同步
public void ejbLoad() { loadRow(); }  // SELECT
public void ejbStore() { storeRow(); } // UPDATE

Finder 查詢方法

  • 強制:ejbFindByPrimaryKey 返回主鍵
  • 可選:業務查詢如 ejbFindByLastName、ejbFindInRange
  • 返回類型:主鍵或 Collection(主鍵集合)
  • 未找到拋出 ObjectNotFoundException(單一)或 FinderException(集合)
public Collection ejbFindByLastName(String name) throws FinderException {
    Collection pks = selectByLastName(name); // JDBC SELECT
    if (pks.isEmpty()) throw new ObjectNotFoundException("無記錄");
    return pks;
}

業務方法設計

  • 封裝業務邏輯,不直接訪問數據庫
  • 依賴容器自動調用 ejbLoad/store 同步
  • 拋出應用異常(如 InsufficientBalanceException),系統異常包裝為 EJBException
public void debit(double amt) throws InsufficientBalanceException {
    if (balance - amt < 0) throw new InsufficientBalanceException();
    balance -= amt; // 容器稍後自動 ejbStore
}

介面定義

Home 介面

public interface AccountHome extends EJBHome {
    Account create(String id, String first, String last, double bal)
        throws RemoteException, CreateException;
    Account findByPrimaryKey(String id) throws FinderException, RemoteException;
    Collection findByLastName(String last) throws FinderException, RemoteException;
    Collection findInRange(double low, double high) throws FinderException, RemoteException;
}

Remote 介面

public interface Account extends EJBObject {
    void debit(double amt) throws InsufficientBalanceException, RemoteException;
    void credit(double amt) throws RemoteException;
    String getFirstName() throws RemoteException;
    String getLastName() throws RemoteException;
    double getBalance() throws RemoteException;
}

客戶端使用

AccountHome home = (AccountHome) ctx.lookup("AccountHome");
Account duke = home.create("123", "Duke", "Earl", 0.00);
duke.credit(88.50);
duke.debit(20.25);
System.out.println(duke.getBalance()); // 68.25

現代替代:JPA

EJB 3.0+ 以 JPA (EntityManager + @Entity) 替代 Entity Bean,提供更輕量、標準化的 ORM 方案,建議新項目直接使用 JPA。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved