在
WebSphere Business Integration Server Foundation V5.1 发布之前,用户可以在会话 bean
或数据逻辑方法中使用存储过程。后来,需要在 CMP 方法中实现叠加过程。在 WebSphere Business Integration
Server Foundation V5.1 中,容器管理的方法通过将叠加逻辑移到生成的模板中,从而简化了 CMP bean
中的逻辑,这和今天的将逻辑移到生成的 FunctionSet 类中是类似的。但是仍需要用户的干预,将叠加逻辑插入到生成的模板中。
This method gets the number of transactions of a particular * transaction type in a certain period of time, for example, * how many times the account has been withdrawn in the past month.
* *
This method uses stored procedure * getNumberOfTransactions(String id, String transactionType, Timestamp fromTime, * Timestamp toTime). * This stored procedure gets the number of transactions of a particular * transaction type within a certain time period.
* * @param transactionType The transaction type * @param startTime The start time for the search. * @param startTime The end time for the search. * * @return int The number of the transactions */ public abstract int getNumberOfTransactions(String transactionType, java.sql.Timestamp startTime, java.sql.Timestamp endTime) throws InvalidTransactionTypeException;
选择
Target Server => Modify...,然后从列表中选择
Integration Server 5.1 作为目标服务器。选中
Update AR modules and utility projects to the selected target server,然后单击
OK。
现在已经用目标服务器 Integration Server 5.1 设置了 BankAccount 项目和它的模块,因此该项目能使用
WebSphere Business Integration Server Foundation V5.1 附带的特定功能。
不要关闭
UserDefinedPushDownMethodsImpl
类中的 WebSphere Business Integration Server Foundation
给定的连接。如果您的UserDefinedPushDownMethodsImpl 方法返回一个 ResultSet
记录,而该类中的连接是关闭着的,处理 ResultSet 时,WebSphere Business Integration Server
Foundation 将抛出一个 “ResultSet has already closed” 异常。
/** * User-defined push-down method getNumberOfTransactions. * If the bean no longer exists in the backend datastore, then you should * throw a javax.ejb.NoSuchEntityException. * * @param arg0 Push-down method Parameter #0 * @param arg1 Push-down method Parameter #1 * @param arg2 Push-down method Parameter #2 * @param bean Reference to the bean implementation class * @param accessIntent Reference to the access intent settings to be used for * this method * @param connection The CCI connection to the back-end system. This * connection was previously obtained (by the EJBToRAAdapter implementation) * via connectionFactory.getConnection(connectionSpec). For non-relational, * non-CCI based beans, this will be null and the user will have to manually * connect to the back-end system and close the connection before returning. * * @return The return type of this push-down method is int * @exception com.ibm.websphere.sample.exception.InvalidTransactionTypeException * Thrown if an exception occurs in the data logic method * @exception ResourceException Any other exceptions are wrapped in a * ResourceException. */
callableStatement.execute(); // create a record to store all the return values IndexedRecord rec = helper.createIndexedRecord(); // assume that there are three output parameters: one integer and two // String fields. rec.add(new Integer(callableStatement.getInt(1))); rec.add(callableStatement.getString(2)); rec.add(callableStatement.getString(3)); // return a wrapper of this record. return helper.createCCIRecord(rec);
callableStatement.execute(); // create a record to store all the return values IndexedRecord rec = helper.createIndexedRecord(); // assume that there are three output parameters: one integer and two // String fields. rec.add(new Integer(callableStatement.getInt(1))); rec.add(callableStatement.getString(4)); rec.add(callableStatement.getString(6)); // return a wrapper of this record. return helper.createCCIRecord(rec);
callableStatement.execute(); ResultSet rs = callableStatement.getResultSet(); // create a top level record to save each inner record IndexedRecord returnValue = helper.createIndexedRecord(); IndexedRecord item = null; // this is the inner record while (rs.next()) { // create an IndexedRecord to store the values item = helper.createCCIIndexedRecord(); item.add(new Integer(rs.getInt(1))); item.add(rs.getString(4)); item.add(rs.getString(6)); // add this record to the top level record returnValue.add(item); } // return a wrapper of this composite record return helper.createCCIRecord(returnValue);
public int getNumberOfTransactions( String arg0, java.sql.Timestamp arg1, java.sql.Timestamp arg2, BankAccountBean bean, AccessIntent accessIntent, Object connection) throw com.ibm.websphere.sample.exceptin.InvalidTansactinTypeException, ResourceException { ......................... // Assume that the 4th parameter is used to pass in the // lockType to the stored procedure callableStatement = helper.prepareCall(connection, "{call getAccountByBalance(?, ?,?,?)}"); // use the accessIntent parameter that is passed into this method // to get the lock type. int lockType = helper.getLockType(accessIntent); callableStatement.setInt(4, lockType); // In the stored procedure getAccountBalance, it uses the // lockType to determine which SELECT statement to use.
// assume the error code is from the CallableStatement. If error code // is not 0, then return a user defined InvalidTypeException. ResultSet rs = CallableStatement.getResultSet(); if (rs.next()) { returnValue = rs.getInt(1); if (returnValue != 0) throw new mycomp.account.InvalidTypeException(returnValue); else { // process the return value here... } }
This BankAccountEJB EJB file is used for handling BankAccount transactions using stored procedure support. The stored procedure logic is described in the com.ibm.websphere.sample.BankAccountSPFile which stores in this JAR file.
BankAccountEJB BankAccount
com.ibm.websphere.sample.BankAccountSPFile 文件包含处理输入/输出参数和调用存储过程的逻辑。当将 bean 部署到 WebSphere Business Integration Server Foundation 中时,部署者将逻辑注入到
UserDefinedPushDownMethodsImpl 类中。实例如下,清单 13 显示了这个 BankAccountSPFile。
清单 13. mycomp.BankAccountSPFile 实例
This file documents the stored procedure invocation in the BankAccountUserDefinedPushDownMethodsImpl
1) getNumberOfTranasction CallableStatement: call getNumberOfTransactions(?, ?, ?,?) Input parameters and position into CallableStatement:
Parameter position type name 1 String accountId 2 String transactionType 3 Timestamp fromTime 4 Timestamp toTime 5 int (out) numOfTransactions Output parameters handling: int returnValue = callableStatement.getInt(5); Exception: InvalidTransacationTypeException -- this exception is thrown when the transaction type is invalid Exception -- no resultSet returned from getNumberOfTransactions
2) ejbRemove CallableStatement: call deleteAccount(?) Input parameter and position into CallableStatement:
Parameter position type name 1 String accountId Output parameters handling: none Exception: ResourceException -- this exception is thrown if stored procedure can't delete the row. You must wrap the SQLException in this ResourceException. 3)... more methods...
/** * User-defined push-down method getNumberOfTransactions. * If the bean no longer exists in the backend datastore, then you should * throw a javax.ejb.NoSuchEntityException. * * @param arg0 Push-down method Parameter #0 * @param arg1 Push-down method Parameter #1 * @param arg2 Push-down method Parameter #2 * @param bean Reference to the bean implementation class * @param accessIntent Reference to the access intent settings to be used for this method * @param connection The CCI connection to the back-end system. This * connection was previously obtained (by the EJBToRAAdapter implementation) * via connectionFactory.getConnection(connectionSpec). For non-relational, * non-CCI based beans, this will be null and the user will have to manually * connect to the back-end system and close the connection before returning. * * @return The return type of this push-down method is int * * @exception com.ibm.websphere.sample.exception.InvalidTransactionTypeException Thrown * if an exception occurs in the data logic method * @exception ResourceException Any other exceptions are wrapped in a * ResourceException. */ public int getNumberOfTransactions( String arg0, java.sql.Timestamp arg1, java.sql.Timestamp arg2, BankAccountBean bean, AccessIntent accessIntent, Object connection) throws com.ibm.websphere.sample.exception.InvalidTransactionTypeException, ResourceException { Tr.entry( WsJrasTraceLogger.TYPE_ENTRY_EXIT, this, "getNumberOfTransactions(String, java.sql.Timestamp, java.sql.Timestamp, BankAccountBean, AccessIntent, Object)", new Object[] { arg0, arg1, arg2, bean, accessIntent, connection }); int returnValue = 0; java.sql.CallableStatement callableStatement = null; try { callableStatement = helper.prepareCall( connection, "{call getNumberOfTransactions(?, ?, ?, ?, ?)}"); // Begin customer-written code to populate callableStatement // Place code here like: callableStatement.setXXX(X, argX); String accountId = bean.getAccountId(); callableStatement.setString(1, accountId); callableStatement.setString(2, arg0); callableStatement.setTimestamp(3, arg1); callableStatement.setTimestamp(4, arg2); callableStatement.registerOutParameter(5, java.sql.Types.INTEGER); // End customer-written code to populate callableStatement callableStatement.execute(); // The returnValue variable should be set to the appropriate value returnValue = callableStatement.getInt(5); } catch (ResourceException re) { Tr.exception( WsJrasTraceLogger.TYPE_ERROR_EXC, this, "getNumberOfTransactions(String, java.sql.Timestamp, java.sql.Timestamp, BankAccountBean, AccessIntent, Object)", re); throw re; } catch (Exception e) { ResourceException re = helper.createResourceException(e, this.getClass()); Tr.exception( WsJrasTraceLogger.TYPE_ERROR_EXC, this, "getNumberOfTransactions(String, java.sql.Timestamp, java.sql.Timestamp, BankAccountBean, AccessIntent, Object)", re); throw re; } //Note that if the return code from the back-end datastore interaction //indicated that a user-defined exception (declared in the push-down //method's signature) should be thrown, then throw it here. Tr.exit( WsJrasTraceLogger.TYPE_ENTRY_EXIT, this, "getNumberOfTransactions(String, java.sql.Timestamp, java.sql.Timestamp, BankAccountBean, AccessIntent, Object)", new Integer(returnValue)); return returnValue; }
要导出 EAR 文件,请选择
File => Export...,然后将应用程序安装到 WebSphere Business Integration Server Foundation 中。
在 WebSphere Business Integration Server Foundation 中安装这种 CMP EJB 组件(利用存储过程功能安装 CMP)和安装任何典型的 CMP EJB 组件是类似的,因此本文没有涉及到这方面的内容。用户可以从
下载文件中安装 BankAccountCMPSP 应用程序,运行应用程序客户端来查看如何使用存储过程。有关详细信息请参阅
BankAccountSample.zip 文件中的
readme.txt。这个 ZIP 文件包含了
BankAccountBeanUserDefinedPushDownMethodsImpl 和
TransactionHistoryBeanUserDefinedPushDownMethodsImpl 的源代码。