将存储过程封装为EJB组件的方法
板发表信息的数据)。您可能要问:为什么会这样呢?
某些 DBMS 要求,在获得任何输出参数值之前,要从存储过程返回的结果集检索所有需要的值。由于这种要求,在通过 getParameter() 方法进行特别请求之前,CallableStatement bean 不从数据库获得任何输出参数,因为何时从结果集检索数据是由用户控制的。缺省情况下,在执行存储过程之后,将自动检索结果集,并将其存储在高速缓存中。但是,必须显式检索输出参数,并将其存储在高速缓存。
检索完输出参数之后,将 DAB CallableStatement 返回给 EJB 组件的调用程序。该对象现在包含过程返回的所有输出(包括结果集),和帮助调用程序正确分析对象语法的适当的元数据。当我们查看调用会话 bean 封装器方法的样本客户机应用程序时,将看到如何去做。
如果您熟悉 JDBC,可能会问:为什么不在此代码块中显式发出 commit 语句。确实,如果使用的是 JDBC 1.0 样式的连接,可能需要(否则,当在 "finally" 块中关闭数据库连接时,将逆序恢复所做的工作)。但是,使用 DataSource 并接受 WebSphere 缺省的 EJB 组件属性 (TX_REQUIRED),WebSphere 将自动为我们的工作提供事务管理。因此,不再需要显式的 commit 语句。
处理异常与关闭打开的资源 当然,在执行会话 bean 时可能会出错。因此,需要提供异常处理。代码块 6 包括适合于与 EJB 1.0 兼容的 bean 的简单异常处理程序。它只是捕获遇到的任何异常,包括一个适当的错误消息,并将异常作为新的 RemoteException 抛回给调用程序。
另外,该代码块还包含一个 "finally" 块,以确保关闭所有打开的资源。在这里,释放任何与 CallableStatement 对象关联的资源。下一步,除去在工作中所用的任何对连接的 DAB 引用。最后,确保关闭 WebSphere 连接。
构建客户机应用程序 构建了 EJB 封装器方法之后,该集中讲述客户机应用程序了。与 EJB 组件一样,首先展示客户机应用程序的完整代码样本。然后,将详细讲述个别代码块。
这里显示的客户机应用程序 -- ClientAnalysis -- 使用 RMI/IIOP 与 EJB 组件通信。其工作很简单:创建会话 bean,调用它的 lookupClient(...) 方法,处理该方法返回的 DAB CallableStatement 对象,然后除去 bean。将该应用程序编写成处理 CallableStatement 的通用客户机,即,假设事先不知道有关 CallableStatement 内部结构的任何信息。相反,我们严格依赖其中包含的元数据,来分析对象的语法,并使用其相关组件,如过程返回的输出参数和结果集。这种方法演示了通用的编码模式,可以在处理 CallableStatement 的任何应用程序中使用。就这样,它补充了在无状态会话 EJB 组件中对封装存储过程所用的通用编码模式。
创建 EJB 组件并调用其封装器方法
客户机应用程序的代码块 1 以 main(...) 方法开始。它指定感兴趣的客户标识,并调用一个私有辅助方法,来获得正在使用的会话 EJB 组件。执行完 bean 之后,调用 lookupClient(...) 方法。这是封装 CLIENTREPORT 存储过程并返回 DAB CallableStatement 的方法。
需要详细讲述私有辅助方法 -- createEJB()。因为 EJB 组件创建工作可能会根据所用的 Web 应用程序而略有不同,所以,选择将这个工作隔离成单独的方法。特别是,由于与该上下文相关的特定属性将会改变,所以,获得 JNDI InitialContext 的方法可能不同。
该 createEJB() 方法创建一个散列表,然后用适合于软件环境的值填充。下一步,创建一个新的 InitialContext 对象,该对象用于通过 JNDI 服务获得对 EJB 组件的远程引用。因为从 JNDI 上下文返回 JNDI(这是在 IIOP 之上使用 RMI 的编码需求),所以,限制了该远程引用。获得 EJB 组件宿主之后,创建一个无状态会话 bean,然后将其返回给客户机应用程序的 main 方法。
处理返回的对象 客户机应用程序的代码块 2 处理 EJB 组件返回的 DAB CallableStatement 对象。首先定位与 CallableStatement 关联的根元数据对象。因为 CallableStatements 可以获得多个结果集,所以,多个 StatementMetaData 对象可以链接在一起,并包括在 CallableStatement 中。而链的根总包含描述 SQL 语句的元数据和相关参数,因此,这就是我们的开始之处。这允许我们获得 CallableStatement 中包括的参数数目。返回的数目将包括过程的所有 IN、INOUT 和 OUT 参数。通过使用循环,可以处理所有参数并打印每个参数的相关信息,包括参数名、相应的 Java 类和模式(指明 IN、INOUT 或 OUT 模式的数字)。
下一步,查看结果集并处理它们。首先,确定 CallableStatement 对象中包括的结果集数目。通过使用循环,可以获得每个用 DAB SelectResult 对象表示的结果集。然后,使用另一个私有辅助方法 processRS(...) 来处理结果集。processRS(...) 方法确定传递给 SelectResult 并包含在其中的行和列的数目。假设有一些行存在,它使用嵌套循环来打印有关所有行中的所有列的信息。该信息包括列名和它的值。
目前为止,客户机应用程序的工作几乎完成。代码块 3 除去会话 bean,打印一行表明已完成,然后终止。当然,在代码块 3 之后的代码处理任何遇到的异常。在这里,只打印一个堆栈跟踪。
总结 希望您已理解会话 EJB 组件如何利用封装在旧有 DBMS 存储过程中的商业逻辑。这样做的其它可能的好处包括:减少 EJB 服务器和 DBMS 之间的网络通信量,提高生产力,以及降低总体软件维护成本。如果遵循本文中列出的编码模式,则无论与过程相关的参数或结果集如何,您都可以将任何类型的存储过程作为方法封装在无状态会话 bean 中。而且,您将可以使用通用编码模式来调用任何这样的 EJB 组件,并处理它返回的对象,而不必事先知道该对象的内部结构。
上一页 [1] [2]
进入问吧