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

J2EE 多層架構設計實戰:基於 Session Facade、Business Delegate、DAO 模式的完整框架

     編輯:J2EE

架構核心原則

One Transaction, One Invocation — 每個業務用例對應一次遠程調用、一個事務邊界。此思想貫穿五層架構:

  1. Persistence Layer — 資源訪問封裝
  2. Domain Layer — 業務實體與規則 (BMP/CMP Entity Bean)
  3. Server Layer — 用例封裝 — Session Facade
  4. Application Layer — 表現層隔離 — Business Delegate
  5. Presentation Layer — JSP/Servlet/CSS/XSL

各層詳細設計與代碼實現

1. Persistence Layer — Data Access Command Bean 模式

封裝 JDBC 操作,隔離 Domain Layer 與數據庫細節。

// Database.java — 連接池獲取
public class Database {
    public static Connection getConnection() throws Exception {
        Context ctx = new InitialContext();
        DataSource ds = (DataSource) ctx.lookup("jdbc/template");
        return ds.getConnection();
    }
}

// DataAccessBean.java — 統一 SQL 執行模板
public class DataAccessBean {
    private Connection con;
    private PreparedStatement pstt;
    private String sql;

    public void setSql(String sql) throws NotConnectionException { ... }
    public void setString(int col, String val) { ... }
    public void setInt(int col, int val) { ... }
    // ... 其他 setXxx 方法

    public ResultSet executeQuery() throws SQLException { ... }
    public int executeUpdate() throws SQLException { ... }
    public boolean execute() throws SQLException { ... }
    public void close() throws NotCloseException { ... }
}

異常類:NotConnectionException、NotCloseException。

WSAD 配置連接池: Server Configuration → Data Source → JDBC Driver (Oracle Thin) → Data Source (JNDI: jdbc/template) → Resource Property URL=jdbc:oracle:thin:@host:1521:sid。

2. Domain Layer — BMP/CMP Entity Bean 統一範式

命名規範: com.模塊.domain.實體名

通用屬性修改模式 — Generic Attribute Method:

// 遠程接口
public interface TDomain extends EJBObject {
    void changeValue(HashMap attri) throws RemoteException;
}

// Bean 實現
public void changeValue(HashMap attri) {
    if (attri.containsKey("name")) setName((String)attri.get("name"));
    if (attri.containsKey("sex")) setSex(((String)attri.get("sex")).charAt(0));
    if (attri.containsKey("birth")) setBirth((String)attri.get("birth"));
}

優勢:單次遠程調用完成多字段更新,減少網絡開銷;擴展字段無需修改接口簽名。

BMP 關鍵回調實現: ejbLoad/Store/Passivate/Activate/Remove/Create/PostCreate/FindByPrimaryKey 統一使用 DataAccessBean 操作數據庫,isModified 標記優化 ejbStore。

CMP 差異: 字段聲明為 public,Finder 方法在 Home 接口聲明,SQL 在 EJB Extension Editor 配置 (EJB QL / Where Clause),無需 Bean 類編寫持久化代碼。

3. Server Layer — Session Facade 封裝用例

// Tserver.java (Remote)
public interface Tserver extends EJBObject {
    RowSet readData(String birth1, String birth2) throws RemoteException;
    void create(String id, String name, String birth, String sex) throws Exception, RemoteException;
}

// TserverBean.java
public RowSet readData(String birth1, String birth2) {
    // JDBC for Reading 模式:直接用連接池 + CachedRowSet,繞過 Entity Bean 開銷
    Connection con = Database.getConnection();
    PreparedStatement ps = con.prepareStatement("select * from template1 where birth>=? and birth<=?");
    ps.setString(1, birth1); ps.setString(2, birth2);
    CachedRowSet rs = new CachedRowSet();
    rs.populate(ps.executeQuery());
    rs.setTableName("template1");
    return rs; // 可序列化傳遞給客戶端
}

public void create(String id, String name, String birth, String sex) throws Exception {
    TDomainHome home = getTDomainHome(); // JNDI 查找
    try {
        TDomain domain = home.findByPrimaryKey(new TDomainKey(id));
        HashMap attri = new HashMap();
        attri.put("name", name); attri.put("birth", birth); attri.put("sex", sex);
        domain.changeValue(attri); // 更新
    } catch (FinderException fe) {
        home.create(id, name, birth, sex.charAt(0)); // 新建
    }
}

數據傳輸模式選擇: HashMap (少量字段)、DTO (多行/頁面綁定)、RowSet (查詢結果集)、XML (異構集成)。

4. Application Layer — Business Delegate + Home Factory

// Tbusiness.java (Business Delegate)
public class Tbusiness {
    public Tserver getTserver() throws Exception {
        HomeFactory factory = HomeFactory.builder();
        TserverHome home = (TserverHome) factory.findBy(TserverHome.class);
        return home.create();
    }

    public void updateAndCreate(String id, String name, String birth, String sex) throws Exception {
        // 參數校驗
        if (sex.length()!=1 || birth.length()!=8) throw new Exception("error data formation");
        getTserver().create(id, name, birth, sex);
    }

    public RowSet showData(String birth1, String birth2) throws Exception {
        if (birth1.length()!=8 || birth2.length()!=8) throw new Exception("error data formation");
        RowSet rs = getTserver().readData(birth1, birth2);
        if (rs==null) throw new Exception("return value is null");
        return rs;
    }
}

// HomeFactory.java — 單例 + 享元模式緩存 Home 接口
public class HomeFactory {
    private static HomeFactory factory;
    private static HashMap map = new HashMap();
    private static final String[] JNDI_NAMES = {"ejb/Tserver"};
    private static final Class[] CLASSES = {TserverHome.class};

    private HomeFactory() throws HomeFactoryCreateException {
        Context ctx = new InitialContext();
        for (int i=0; i

作用:隔離 JNDI 名稱變更、緩存 Home 接口減少查找開銷、統一異常轉換、參數校驗前置。

5. Presentation Layer — JSP/Servlet 示例

JSP 使用 JSTL/EL 顯示 RowSet,Servlet 委派給 Tbusiness,保持控制器輕薄。

部署與調試策略

  • 模塊調試: 客戶端測試環境直接調用 EJB (JNDI: ejb/TDomain)。
  • 集成調試: 完整 EAR 部署,驗證層間交互。
  • 系統調試: 專人負責端到端業務流程驗證。

總結

該框架通過五層分離、經典模式組合 (Session Facade + Business Delegate + DAO Command Bean + Generic Attribute Method + JDBC for Reading + Home Factory),實現了高性能、可復用、可擴展的 J2EE 應用架構。核心代碼已在 WSAD 環境驗證,可直接遷移至其他 J2EE 容器。

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