引言
在我们以前的文章 将 db2 information integrator 用于 j2ee 开发:成本/效益分析中,我们描述了一个 java™ 2 企业版(j2ee)项目,它被设计成用来评估实现需要从三种不同的数据源检索与合并数据的 servlet 时的折中方案.我们构建了一组 servlet,它们使用 ibm® db2® information integrator 来模拟不同数据的单点映像,并且我们构建了另一组 servlet,它们直接使用每个必要的数据源.在本文(我们系列中的第二篇)中,我们将完整地向您讲述我们开发工作的细节.我们将回顾我们的设计.向您展示我们的部分代码并描述我们在实现这些 servlet 时所面临的挑战.在我们的下一篇文章(我们系列中的最后一篇)中,我们将讨论性能问题.
快速回顾
如果您没有机会阅读我们的 上一篇文章,我们将在这里对它作一下回顾.然而,我们强烈建议您回顾一下这篇文章,因为它提出了我们想要实现的应用方案.描述了数据分布方案并说明了我们的每个 servlet 发出的查询.我们的两组 servlet 都使用存储在 oracle 表.db2 表与 microsoft® excel 电子表格中的数据.这些数据基于一个部件分销的数据库,它跟踪部件.供应商.客户与订单等.
我们发现可以使用两种软件体系结构(即,使用 db2 information integrator 或使用直接数据访问)中的任一种来成功地构建使用这些不同数据的 servlet.然而,我们也发现:
当我们使用 db2 information integrator 时,我们减少了大约 40% 的 servlet 代码与至少 50% 的开发时间. 当我们使用 db2 information integrator 时,我们不必处理复杂的查询分解问题.如果这些问题处理不当将导致错误的结果或糟糕的性能,而 db2 information integrator 的全局查询优化器能够自动处理这些问题. 使用 db2 information integrator 的 servlet 的查询响应时间通常与我们观察到的直接数据访问实现的响应时间不相上下.有时候,我们甚至观察到使用 db2 information integrator 时性能更好.就我们所期望的 j2ee 开发者对该环境的了解程度而言,值得注意的是我们可以做一些工作来使直接数据访问的方案很好地被执行.总体的体系结构与设计
我们的 servlet 用 jdbc 通过 db2 information integrator 来访问数据或直接访问每个数据源.只要可能,我们就使用 datasource 连接(合用连接),它通常能更有效地利用系统资源.我们通过在每个 servlet 的 init方法中对这些 datasource 执行 jndi 查询来进一步寻求保持代码效率.当通过 db2 information integrator 访问远程数据时,我们的 servlet 对跨所有必要数据源的昵称与昵称的 union all 视图发出查询.当直接访问远程数据时,我们的 servlet 对每个数据源分别发出查询,并且将结果集插入本地 db2 实例中的辅助表,然后查询这些表以得到最后的结果.这极大地简化了我们的编程任务,因为另一方面,在我们应用程序空间中对所有数据进行组合.排序.聚集与分组需要相当大的工作量.所以我们反过来选择利用本地的 dbms 表来帮助我们完成工作,因为根据我们的判断,dbms 对大多数 websphere® 开发者是可用的.注意,我们试图在远程数据源上过滤掉尽可能多的数据来最小化网络流量并进一步提高我们的 servlet 的效率,这些 servlet 直接使用每个数据源.
我们的所有 servlet 的表示逻辑是简单的.我们使用 html 或 jsp 来获取我们 servlet 的输入参数并发布结果.
完成所有设置
在我们编写 servlet 以前,我们必须设置我们的环境.幸运的是,这些工作并不难.对于所有的工作,我们按标准过程安装与配置 websphere studio v5 的 application developer 配置.我们也在相同的机器上同样按照 db2 information integrator 的标准配置过程来安装 db2 information integrator.对一组 servlet,我们使用 db2 information integrator 的联邦技术来处理不同的数据.对于另外一组 servlet,我们仅将 db2 information integrator 用作本地数据库存储管理器.也就是说,在我们的 servlet 手工地连接到每个必要的源并从该源检索数据以后,我们用 db2 information integrator 来为我们的 servlet 存放辅助表.
配置 db2 information integrator
要使用 db2 information integrator 的联邦功能,我们安装必备软件(按照产品手册中的定义)来访问目标数据源.然后我们创建必要的联邦数据对象,包括每个目标数据源的包装器.每个必需的服务器实例的服务器对象.用于远程认证的用户映射以及远程数据的昵称.在大多数公司中,通常由数据库管理员而不是 j2ee 程序员来完成这些工作,而且 db2 information integrator 提供了一个 gui 工具来简化这个过程.然而,我们选择编写通过命令行处理器发出 sql 语句的脚本.这里是一些 sql 语句,我们发出这些 sql 语句来配置对 oracle dbms 的访问权.在脚本编制环境中,两个连字符(“--”)表示注释.
-- create the oracle wrapper object. create wrapper net; -- create the oracle server object. -- we need to specify a previously defined wrapper object -- and identify valid account information for our oracle database. -- we also need to specify the node where the oracle instance is running. create server jaqora type oracle version 8 wrapper net8 authorization "demo" password "cdidemo" options (node iidemo2); -- create a user id mapping between a valid db2 information integrator -- account ("db2admin") and a valid oracle account ("demo"). create user mapping for db2admin server jaqora options (remote_authid demo, remote_password cdidemo); -- create a local db2 information integrator nickname("ora_part") -- for a remote oracle table ("jaqora.demo.part"). create nickname ora_part for jaqora.demo.part;有时我们需要更改 db2 information integrator 执行的缺省的数据类型映射.例如,在缺省情况下,db2 information integrator 将 oracle 表中的数字数据映射为 db2 double 数据类型,但是这并不总是适合于我们的工作.更改缺省的映射很简单;我们只要改变我们的昵称定义,如以下所示:
-- represent the "p_partkey" column of the "ora_part" table as an integer -- locally alter nickname ora_part alter column p_partkey local type integer;我们执行类似的语句来配置对远程 db2 服务器与本地 excel 电子表格(我们用 db2 information integrator 的 odbc 包装器通过 jdbc/odbc 桥来访问它)的访问权.
最后,我们的某些查询需要使用跨我们三个数据源的昵称的 union all 视图.我们通过从相关的昵称选择所有列并添加一个服务器属性列来创建这些视图,该服务器属性列用来跟踪最初存放这些数据的数据源.这个添加的列帮助我们保留某些查询的正确的语义,我们将稍后说明这一点.以下是我们的视图定义之一:
-- create a consolidated view of part data stored in a excel, oracle, and db2 create view fed_part as select db2_part.*, db2 as p_server from db2_part union all select ora_part.*, ora as p_server from ora_part union all select odbc_part.*, xls as p_server from odbc_part;如果您想要回顾作为我们系统配置工作的一部分而发出的 sql 语句,请参阅 附录 a.如果您觉得所有这些显得太繁复了,那么请您记住:您可以使用可生成所有这些 ddl 的 gui.
配置直接的数据访问环境
对于直接的数据访问,我们也需要安装适当的必备软件.这些软件随所涉及的数据源的不同而不同,我们可以查阅特定于供应商的产品文档来完成这些工作.当连接能够正常工作时,我们创建本地 db2 表来存储将从我们的查询返回的中间结果.这些表随所涉及的查询的不同而不同.我们必须考虑计划如何分解每个目标数据源的原始查询,并且确保我们创建的辅助表能够容纳返回的结果.我们总是为每个查询创建至少一个辅助表(在某些情况下,我们创建多个辅助表).在数据库管理员与 j2ee 程序员合作并理解了该程序员的需求以后,很可能由数据库管理员来创建这些对象.
在了解了您要在 db2 中创建的表的结构以后,这个过程就简单了.我们选择从命令行处理器发出 sql 语句.以下是我们要创建的辅助表(它存放我们第一个查询的中间结果)的一个例子:
create table temp_query1 ( p_partkey integer, p_name varchar(55), p_mfgr char(25), p_type varchar(25))如果您确实要了解每个辅助表的定义,请参阅 附录 b.
管理连接
在试图发出查询以前,我们所有的 servlet 需要建立到相应数据源的连接.只要可能,我们就使用 websphere 合用连接(datasource 对象),因为这些连接会改善系统的效率.已经证实,对于使用 db2 information integrator 来访问数据的 servlet,我们可以方便地完成这些工作.对于直接访问每个数据源的 servlet,我们发现只能使用 websphere 合用连接来访问我们的远程 db2 universal database™(udb)与 oracle 数据源.对于我们的 excel 数据,我们必须依赖于由用户管理的连接(jdbc 1.0 类型的连接),等一下我们会讨论其原因.通过 db2 information integrator 建立连接
当使用 db2 information integrator 时,我们的 servlet 只建立一个连接(连接到 db2 information integrator 服务器).只要这些 servlet 在查询中引用一个昵称(或涉及昵称的一个视图),db2 information integrator 就会自动地建立到不同数据源所需要的连接以便能检索相应的数据.所有这些对我们是透明的.另外,因为 db2 information integrator 对于 websphere studio 就像是一个标准的 db2 udb v8 服务器,所以我们只需使用内置的向导定义一个 datasource 对象.这里是我们的一个 servlet(它是使用 db2 information integrator 的 servlet 之一)中的连接代码样本:
... 下一页