推薦無狀態會話 Bean:資源消耗少、並發性能好、無會話狀態管理開銷。適用於封裝無會話親和性的存儲過程調用。
直接映射為 EJB 方法參數,類型對應 Java 基本類型/包裝類。
存儲過程可能返回:多個 OUT/INOUT 參數 + 多個結果集。需封裝為可序列化對象傳回客戶端。
IBM Data Access Bean (DAB) 庫 提供 com.ibm.db.CallableStatement,優勢:
CLIENTREPORT:1輸入+2輸出+2結果集)Analysis)public interface Analysis extends EJBObject {
CallableStatement lookupClient(Integer clientId) throws RemoteException;
}
// 1. 獲取 DataSource (JNDI + 連接池)
Context ctx = new InitialContext(env);
DataSource ds = (DataSource) ctx.lookup("jdbc/LocalDB2Sample");
Connection conn = ds.getConnection(user, pass);
conn.setAutoCommit(false); // 容器管理事務
// 2. 構建 CallableStatement 元數據
StatementMetaData meta = new StatementMetaData();
meta.setSQLString("{call CLIENTREPORT(?, ?, ?)}");
meta.registerParameter("clientId", Types.INTEGER, ParameterMetaData.IN);
meta.registerParameter("name", Types.VARCHAR, ParameterMetaData.OUT);
meta.registerParameter("email", Types.VARCHAR, ParameterMetaData.OUT);
CallableStatement cstmt = new CallableStatement();
cstmt.setMetaData(meta);
cstmt.setDatabaseConnection(new DatabaseConnection(conn));
// 3. 設置輸入參數並執行
cstmt.setParameter("clientId", clientId);
cstmt.execute();
// 4. 顯式獲取輸出參數(結果集自動緩存)
cstmt.getParameter("name");
cstmt.getParameter("email");
return cstmt; // 返回封裝完整結果的對象
客戶端無需預知結果結構,完全依賴元數據動態解析:
// 1. 創建 EJB 引用
Context ctx = new InitialContext(env);
Object ref = ctx.lookup("ejb/Analysis");
AnalysisHome home = (AnalysisHome) PortableRemoteObject.narrow(ref, AnalysisHome.class);
Analysis bean = home.create();
// 2. 調用並處理返回的 CallableStatement
CallableStatement cs = bean.lookupClient(new Integer(123));
// 3. 通用參數處理
StatementMetaData rootMeta = cs.getMetaData();
for (int i=0; i
使用 DataSource + 容器管理事務 (TX_REQUIRED) 時,無需顯式 commit/rollback,容器根據方法完成情況自動處理。
此模式適用於任意存儲過程封裝,實現了:開發效率提升(復用現有邏輯)、運行性能優化(減少網絡交互)、架構靈活性(通用客戶端模式)。