使用 Oracle Warehouse Builder 中的 JDBC 连接层

作者:Yuli Vasiliev

了解如何使用 Oracle Warehouse Builder 11g 第 2 版中的 JDBC 连接层处理 JDBC 可访问源中的数据。

2010 年 10 月发布

可以将业务智能 (BI) 看作从您有权访问的数据中提取业务信息的过程(不管数据格式以及访问它们的方式如何)。因此,原生连接到异构数据源的能力对任何 BI 系统而言都是一项十分重要的功能。

作为一款获取、生成和共享 BI 元数据和数据的功能完备的工具,Oracle Warehouse Builder 可以处理大量的源,包括异构数据库系统、ODBC 源(如 MS Excel 和 MS Access),甚至平面文件。而在实际中,经常需要处理几个不同的数据库系统。

在 Oracle Warehouse Builder 中,可以通过 Oracle 异构服务(网关)或使用 JDBC 作为连接层的代码模板 (CT) 来访问这类数据库系统。前者的应用已经有很长一段时间了,后者对 Oracle Warehouse Builder 11g 第 2 版而言是一种新的方法,更加灵活高效,因为它使您不用完成许多配置工作就可以原生连接到实际上任何 JDBC 可访问数据系统。

概述

除了代码模板,Oracle Warehouse Builder 的 JDBC 连接层还包含一个开放式连接器,该连接器允许连接到异构数据源,还允许提取、转换和集成这些源中的数据。代码模板大多数是通用的,因为它们位于 JDBC 连接层之上,由 JDBC 连接层负责处理数据源细节问题。另外,Oracle Warehouse Builder 使用平台定义来描述如何将非 Oracle 数据库源的原生类型映射到 Oracle Warehouse Builder 的核心类型。

您可能已经猜到,该架构简化了将新平台添加到受支持平台列表的任务,此外,假如您想将一些自定义功能添加到当前代码模板库中,该架构还可以简化添加新代码模板的任务。

例如,假设您想添加对 MySQL 的支持。(截至 OWB 11g R2 发布时,MySQL 仍未列入默认支持的平台列表中。)您只需下载 MySQL JDBC 驱动程序,将它放在 OWB_HOME/owb/lib/ext 目录下,并通过可在 OMB Plus 控制台上运行的 Tcl 脚本为 MySQL 添加平台定义。这类脚本的内容不在本文讨论范围内。但如果您想查看其中某个脚本,请参阅 David Allan 发表的这篇文章,您会在其中发现一个具体示例,介绍了如何将对 MySQL 的支持添加到 Oracle Warehouse Builder 11g 第 2 版中。此外,OTN 上有一个名为“OWB 平台和应用程序适配器可扩展性指南”的白皮书,其内容比 David 的文章更深入。

值得庆幸的是,对于大多数流行数据库平台,您不必添加它们的平台定义,因为 Oracle Warehouse Builder 11g 第 2 版附带了这些平台定义。因此,默认支持的平台列表包括:DB2、SQL Server、Sybase 和 Teradata。不过,在通过使用 JDBC 的代码模板访问任何数据库之前,仍需要从相应供应商那里获得 JDBC 驱动程序并将它放在 OWB_HOME/owb/lib/ext 目录下。

图 1 给出了此处所讨论架构的简化视图:

vasiliev-owb-jdbc-f1 

图 1:OWB 11g R2 环境中使用的开放式连接器组件的高级视图。

如您所见,代码模板库是上述架构的重要组成部分,它由许多代码模板组成。而每个代码模板又由一组预定义任务组成,其中大部分任务通常是 JDBC 任务,比如创建工作表和加载数据。除了 JDBC 任务之外,代码模板还可以包括 Jython、Runtime API、OS 和 Jacl 任务以实现其功能。

其示意图如图 2 所示:

vasiliev-owb-jdbc-f2 

图 2:代码模板由一组预定义任务组成,其中大部分任务通常是 JDBC 任务。

大多数情况下,不必通过逐个任务地研究代码模板的细节来获得某个 ETL 任务的解决方案。Oracle Warehouse Builder 11g 第 2 版提供了一组预定义代码模板,板允许您执行不同的 ETL 任务。预定义代码模板是通过将在 J2EE 运行时环境中运行的代码来实现的。为此,提供了运行在 OC4J 服务器之上的 Control Center Agent (CCA)。要执行专为其量身定做了代码模板的 ETL 任务,首先必须创建与该代码模板相关的 CT 映射。接下来,要将 CT 映射部署到 CCA(CCA 必须已经启动),然后执行该映射,以便执行已定义好的任务。

下图从概念上描述了上述执行模型:

vasiliev-owb-jdbc-f3 

图 3:代码模板技术的执行模型的简化视图。

事实上,事情要比您了解到的稍微复杂一点。如上所述,要受益于代码模板,首先必须创建与该代码模板相关的 CT 映射。Oracle Warehouse Builder 根据代码模板内容生成映射代码。具体来说就是它生成了为了执行必要的 ETL 任务而需要的 Tcl/Java(Jacl) 脚本(Oracle Warehouse Builder 使用称为 Jacl 的 Tcl Java 实现)。然后,当您执行该映射时,CCA 会运行那些包含嵌入式 JDBC 语句的 Tcl/Java(Jacl) 脚本。

示例

在您掌握 Oracle Warehouse Builder 11g R2 中使用的原生异构连接性背后的理念之后,让我们通过一个简单的示例来了解实际工作过程。以下示例演示了如何通过使用代码模板映射和 JDBC 连接,从两个 SQL Server 表中原生提取数据,并在联接它们之后将它们放在另一个 SQL Server 表中。然后展示了如何了解代码模板的内部情况并根据需要定制代码模板,为其添加新的 JDBC 任务。

开始之前

对 Microsoft SQL Server 而言,首先需要从 Microsoft 下载中心下载相应的 JDBC 驱动程序。例如,如果使用 Microsoft SQL Server 2005,则需要下载 Microsoft SQL Server 2005 JDBC Driver 1.0,这是一个 Type 4 JDBC 驱动程序。然后,需要从下载的程序包中提取 sqljdbc.jar 文件,将它放在 OWB_HOME/owb/lib/ext 目录下。

下一步是启动一个 CCA 实例。尽管在设计时不需要 CCA 实例,但在部署和执行时需要它。回忆本文前面“高级视图”部分中的讨论,CCA 是一个代理,它在 OC4J 服务器中执行代码模板。简要回顾一下,代码模板由预定义任务组成,其中大部分任务通常都是 JDBC 任务。要启动该代理,必须执行 OWB_HOME/owb/bin/unix 中的 ccastart 文件或者 OWB_HOME/owb/bin/win32 中的 ccastart.bat 文件(如果是在 Windows 上)。第一次启动该代理时,会提示您输入为 oc4jadmin 用户设置的口令。在本文稍后创建模板映射模块时,将需要用到该口令。

您还需要确保在您将连接到的 SQL Server 实例上启用了 TCP/IP 协议。例如,默认情况下在 SQL Server Express 中是禁用 TCP/IP 的。因此,您必须通过 SQL Server Configuration Manager 启用它,然后重新启动 SQL Server Express 服务。还要确保任何防火墙配置问题均已得到解决。有关这方面的更多信息,可以参阅“Configure a Windows Firewall for Database Engine Access”或“Configuring the Windows Firewall to Allow SQL Server Access”。

创建项目结构

完成前面部分描述的初始步骤之后,即可创建到 SQL Server 数据库的 JDBC 连接,然后在 Warehouse Builder 中的某个项目下,将感兴趣的数据对象中的元数据导入。具体来说,需要在 databases\SQL Server 节点下创建两个模块,一个是源模块,另一个是目标模块,分别映射到 SQL Server 数据库上的源模式和目标模式。接下来,需要在 Template Mappings 节点下创建一个模板映射模块,然后在该模块内创建一个 CT 映射,在映射画布上放置并连接源对象和目标对象。

总而言之,需要确保 Warehouse Builder 和 SQL Server 上有以下对象:

在 SQL Server 上:

  • 两个通过外键相关联的 SQL Server 表,将用作项目中的源表。例如,可以是填充了一些数据的 emps 和 bonus 表。
  • 一个将用作目标表的 SQL Server 表。那么,它可以是 emps_bonus 表。

 

在 Warehouse Builder 上:

  • SQL Server 源模块。必须将此模块连接到包含源表的 SQL Server 模式。
  • SQL Server 目标模块。必须将此模块连接到包含目标表的 SQL Server 模式。
  • 用作 CT 映射容器的模板映射模块,连接到 Warehouse Builder Control Center Agent。
  • 用于保存源、目标、转换和映射操作符的 CT 映射。

 

为了节省空间,我不打算详细介绍如何创建上述对象。具体说明可在文档资料中找到。另外,Mark Rittman 发表的“Oracle Warehouse Builder 11g 第 2 版和异构数据库”中详细论述了如何创建一个类似的项目结构。在本文中,我将重点放在创建 CT 映射上。要完成此任务,您可以按照以下步骤进行:

  1. 在模板映射模块节点下(假设刚才已创建了它),从弹出菜单中选择 New Mapping 创建一个新映射。
  2. 将源表和目标表拖放到新建映射的画布上,源表和目标表必须分别存在于源和目标 SQL Server 模块下。
  3. 从 Component Palette 中,将 Joiner 操作符添加到映射画布上。然后,定义联接条件,连接源表与目标表。以下快照展示了此刻会看到的内容:


vasiliev-owb-jdbc-f4 

图 4:构建 CT 映射的逻辑视图。

  1. 转到映射的 Execution View 上,单击画布窗口左上角的 Default Execution Units 按钮,让 Warehouse Builder 创建相应的执行单元。在这个特定示例中,只创建一个将在 SQL Server 上执行的执行单元。
  2. 将前面步骤中创建的执行单元与相应代码模板关联。为此,转到位于画布下面的 Code Template 面板上。然后,单击 Integration/Load Code Template 选项卡并从选择框中选择想要的代码模板。对于本例,可能想要选择 ICT_SQL_TO_SQL_APPEND 代码模板。

 

在本例中,只使用了一个将在 SQL Server 上执行的执行单元。您可以选择手动创建两个执行单元,为源表和目标表各创建一个。当通过网络在数据库之间移动数据时,尤其在不同平台间移动时,使用多个执行单元十分常见。OWB 为最终在源和目标数据库上执行的每个执行单元生成代码。

如果使用多个执行单元,则需要为每个单元指定一个代码模板,为包含源表的执行单元选择一个加载代码模板,为包含目标表的执行单元选择一个集成代码模板。在这种情况下,Warehouse Builder 将在 SQL Server 数据库中创建一个临时表,先将联接数据加载到临时表中,然后将它们移至目标表中。

部署和执行

现在可以部署通过上述过程创建的 CT 映射了。为此,可以右键单击 Project Navigator 中的映射节点,然后在弹出菜单中选择 Deploy…。部署过程可能需要花费一些时间,如果一切顺利,完成时不会收到任何错误消息。

部署 CT 映射会生成一个 EAR 文件,该文件将被部署到 Warehouse Builder Control Center Agent。因此,可以在 OWB_HOME/owb/jrt/applications 目录下找到这些 EAR 文件。

回到我们的示例,下一步是执行刚才部署的 CT 映射。要启动执行,可以右键单击 Project Navigator 中的映射节点,然后在弹出菜单中选择 Start…。同样,完成代码模板中包含的任务会花费一些时间,这个代码模板通过前面部分讨论的执行单元与 CT 映射关联。

下图中的快照展示了该执行成功完成后可看到的内容:

vasiliev-owb-jdbc-f5 

图 5:CT 映射执行完成。

如果现在查看 SQL Server 数据库中的目标表,会看到该表已填充了两个源表中的数据。

了解内部情况

上述示例很好地展示了在 Warehouse Builder 中使用代码模板来处理涉及非 Oracle 数据源的标准数据管理任务是多么简单。您要做的只是将 CT 映射与相应的内置代码模板关联,然后部署并执行该映射。尽管执行输出可能向您提示代码模板所包含的任务,但为了完成工作您实际上并不需要深入了解代码模板结构。

在实际中,您可能面临需要调整内置代码模板来解决所遇到的问题的情形。当然,直接修改内置模板并不是一个好主意。您可以采用另一种方法,将代码模板导入 Warehouse Builder 项目以生成一个副本,然后根据需要调整这个副本。同样,通过示例可以更好地理解这一点。

回到我们的示例,让我们了解一下,如果需要在单个事务中完成所有插入操作,我们可以做些什么。首先了解一下为何需要这么做。

假设目标表使用从源数据中获取的主键,如果试图开始后续执行,会出现违反主键约束的错误。当然,此行为在意料之中。问题是,在 SQL Server 中,默认事务模式是自动提交的。这实际意味着每个 DML 操作所做的更改都是立即提交的。在我们的示例中,这可能导致出现这样的情况:当遇到第一个重复的主键时,插入操作还只是部分完成,结果是无法回滚已经提交的操作。

当然,可能已经存在解决此问题的现有集成代码模板,或者将在下一个版本中出现。不过,这里的目的是举例说明如何调整现有代码模板来满足您目前的需求。因此,以下步骤将描述如何导入 ICT_SQL_TO_SQL_APPEND 代码模板,然后修改它,以便在单个事务中对 SQL Server 执行多个插入操作。

  1. 在 Project Navigator 中,右键单击 Code Templates 节点,然后选择 New Code Template Folder 创建一个新的 CT 文件夹。

  2. 展开新建的 CT 文件夹,然后右键单击 Integration 节点。

  3. 在弹出菜单中,选择 Import->Code Template 启动 Import Code Template 向导。

  4. 在向导的 Select Files 屏幕上,单击 Browse 按钮,选择 OWB_HOME/owb/misc/CodeTemplates 文件夹。然后将 KM_IKM_SQL_to_SQL_Append.xml 文件从 Directory Files 框移至 Files to Import 框中。

  5. 在向导的 Name Code Templates 屏幕上,提供代码模板的名称。例如,该名称可以是 ICT_ SQL_TO_SQLSERVER_APPEND。(此名称表明 SQL Server 是此 CT 的目标,— 通用代码模板通常只以“SQL_TO_SQL”命名,这意味着适用于任何 SQL 数据库。)

  6. 完成该向导。作为结果,ICT_SQL_TO_SQLSERVER_APPEND 会出现在 Project Navigator 中的 Code Templates/CODE_TEMPLATE_FOLDER/Integration 节点下。

  7. 双击新建的 ICT_ SQL_TO_SQLSERVER_APPEND 节点,在 Code Template Editor 中打开模板结构。

  8. 在 Code Template Editor 中,可以将与模板任务相关的图标拉开,以便理解模板背后的过程流。也可以选择自动布局选项。

  9. 在 Code Template Editor 中,删除连接 4_LOCK_JOURNALIZED_TABLE 任务和 5_INSERT_NEW_ROWS 任务的箭头。

  10. 将一个新的 JDBC 任务从 Component Palette 拖放到 Code Template Editor 中,将它放在 4_LOCK_JOURNALIZED_TABLE 任务和 5_INSERT_NEW_ROWS 任务之间。

  11. 连接 4_LOCK_JOURNALIZED_TABLE 任务与新建的 JDBC_TASK。为此,将光标移到 4_LOCK_JOURNALIZED_TABLE 图标上,按住鼠标左键,然后绘制一条指向 JDBC_TASK 图标的直线。

  12. 用相同的方式连接 JDBC_TASK5_INSERT_NEW_ROWS

  13. 选择 JDBC_TASK 图标,转到位于 Code Template Editor 下方的 Task Editor。

  14. 在 Task Editor 中,单击 Target 选项卡,在该编辑器中键入以下代码:

 BEGIN TRANSACTION

vasiliev-owb-jdbc-f6 

图 6:将一个新的 JDBC 任务添加到代码模板。

  1. 选择 File->Save All 菜单保存所做更改。

现在,可以将新建的代码模板放在 CT 映射中,然后执行该映射(如前文所述)。您可能已经猜到,新建的代码模板是针对 SQL Server 的,因为其他数据库中可能没有 BEGIN TRANSACTION 语句。至少 Oracle Database 中没有这种语句。

您可以将代码模板目标平台属性更改为 SQLServer(因为它使用特定于 SQLServer 的命令),从而只以 SQLServer 平台为目标 — 例如,当以 Oracle 为目标时,此代码模板不会作为映射执行视图中的一个选项出现。

上面只是定制现有代码模板的一个简单示例 — 只添加了一个将执行单个语句的新 JDBC 任务。在其他情况下,可能需要处理也包含 JDBC 语句的 Jython 代码。顺便说一句,要熟悉内置代码模板的结构,您不必导入它。可以转至 Globals Navigator,然后在 Public Code Templates 下,查看 BUILT_IN_CT 文件夹内部。

如果您打算将创建的自定义代码模板放入某个工作区中的所有项目中,可以在 Public Code Templates 下创建新的代码模板文件夹,然后将其导入或复制粘贴到所有项目中。

vasiliev-owb-jdbc-f7 

图 7:在某个工作区的所有项目中纳入自定义代码模板。

总结

从异构源中提取业务信息的必要性在大部分 BI 系统中是无可争辩的事实。本文讨论了如何在 Oracle Warehouse Builder 11g 第 2 版中通过使用 JDBC 作为连接层的代码模板技术对非 Oracle 数据库实现上述目标。您不但了解了如何使用内置代码模板,还了解了如何在必要时调整它们。在得到代码模板的一些经验之后,您可以前进一步,从头创建一个新的代码模板。



Yuli Vasiliev
是一名软件开发人员、自由撰稿人和顾问,目前专攻开源开发、Java 技术、业务智能 (BI)、数据库和面向服务的架构 (SOA)。他是《Oracle Business Intelligence:An introduction to Business Analysis and Reporting (Packt, 2010) 的作者,也是一系列有关 Oracle 技术的其他书籍的作者。