使用 WebSphere Adapter for JDBC 开发 EIS 应用程序的方法及问题

上一篇 / 下一篇  2008-11-07 17:22:48 / 个人分类:IBM

在本文中,我们将首先简要介绍 WebSphere Adapter for JDBC,描述 J2EE 组件如何通过 WebSphere Adapter for JDBC 来连接 DB2数据库。然后我们将提供针对于实际应用的 WebSphere Adapter for JDBC 的解决方案。在此解决方案中,我们通过一个股票管理与交易系统来展示 WebSphere Adapter for JDBC 的用法,描述了如何使用 WebSphere Adapter for JDBC的 Inbound 和 Outbound 功能。另外针对在使用 WebSphere Adapter for JDBC 过程中所碰到的问题,我们将介绍这些问题产生的原因、避免的方法及途径。

摘要

IBMWebSphere Adapter 实现了 J2EE Connector Architecture(JCA),能够帮助在 J2EE 组件和 Enterprise Inforamtion Systems(EIS) 之间进行双向易于管理的连接。而 IBM WebSphere Adapter for JDBC 是专门针对于支持 JDBC 的数据库开发的。WebSphere Adapter for JDBC 由两部分组成:

1. JCA 的实现,这是用来支持 WebSphere Process Server (WPS) 或者 WebSphere Enterprise Service Bus (ESB);

2. 企业元数据发现组件,可以通过这个组件来连接数据库产生 Data Objects 及其他Service Component Architecture(SCA) 组件。

WebSphere Adapter for JDBC 通过提供基于 JCA 的两种编程接口 Inbound 和 Outbound 来实现 EIS 的双向连接。通过 Outbound 操作,WebSphere Adapter for JDBC 把 Data Object 传递给 EIS,进行指定的数据库操作。通过 Inbound 操作,数据库的改变将触发 WebSpher Adapter for JDBC 的相应操作。

在本文中,我们将首先简要介绍 WebSphere Adapter for JDBC,描述 J2EE 组件如何通过 WebSphere Adapter for JDBC 来连接 DB2 数据库。然后我们将提供针对于实际应用的 WebSphere Adapter for JDBC 的解决方案。在此解决方案中,我们通过一个股票管理与交易系统来展示 WebSphere Adapter for JDBC 的用法,描述了如何使用 WebSphere Adapter for JDBC 的 Inbound 和 Outbound 功能。另外针对在使用 WebSphere Adapter for JDBC 过程中所碰到的问题,我们将介绍这些问题产生的原因、避免的方法及途径。以下是本文主要内容:

第一章将介绍 WebSphere Adapter for JDBC 的功能。

第二章将给出一个示例场景描述 WebSphere Adatper for JDBC 在 WID 中的用法,包括如何使用 WebSphere Adapter for JDBC 的 Inbound 和 Outbound 功能。

第三章指出在使用过程中所碰到的各种问题,包括数据库连接驱动的选择等。

本文假定读者已经具有 J2EE 以及 DB2 数据库的基础知识,主要针对那些需要使用 WebSphere Adapter for JDBC 来 开发应用程序设计者而编写的。另外本文也可以作为 WebSphere Adapter for JDBC 开发人员的参考,以便在开发过程中如何避免这些问题的出现。





回页首


一、 引言

1.1 JCA 介绍

在商业整合开发中,J2EE 应用程序经常需要与各种企业信息系统(EIS)交互,以获得所需的资源或数据,如 ERP 系统、SCM 系统以及各种数据库系统等等。现有的传统模式在整合过程中需要开发者为每一对 J2EE 应用和 EIS 系统之间提供交互方式,并且每对 J2EE 应用程序和 EIS 系统之间的交互方式可能完全不同,因此这显然需要花费大量的人力物力,是不现实的。为了解决这个问题,一种称为 J2EE Connector Architecture (JCA) 的标准被提出来,目前最新的版本是 1.5。JCA 1.5 的标准中定义了一个资源适配器(Resource Adapter)组件。任何符合规范的资源适配器,都可以在 J2EE 的应用服务器环境中部署和运行。于是,符合 JCA 规范的 J2EE 应用程序通过资源适配器便能够和不同的 EIS 系统通过同一种方式交互,而符合 JCA 规范的 EIS 系统也能够和不同的 J2EE 应用程序通过同一种方式交互。简言之,符合 JCA 规范的各种 J2EE 应用程序就可以通过资源适配器中实现的标准接口(Common Client Interface)来和符合 JCA 规范的任何 EIS 系统交互。这使得每个 EIS 系统,只需要一个资源适配器,就可以整合到任何标准的 J2EE 应用中去,简化了开发流程。下图是 JCA 1.5的体系结构,包括三个部分:系统协议(System Contracts),用户接口(Client API),资源适配器模块(Resource Adapter Module)。


图1:JCA体系结构
图1: JCA 体系结构

系统协议定义了 J2EE 应用程序和 EIS 系统之间的接口和交互标准,并且由资源适配器模块来实现这些接口,因此资源适配器可以看作是系统协议的实现。下图描述的是 JCA 的系统协议和资源适配器的体系结构。

系统协议分为三个部分:

  • 连接管理协议,它提供了一种管理和缓存 EIS 连接实体的机制,包括如何建立连接,如何管理连接的生命期等,比如图2中的 connection 等模块;
  • 事务协议,它提供了两种事务管理模式,可以由 J2EE 应用服务器来管理事务,也可以由 EIS 来管理,比如图2中的 LocalTransaction 模块;
  • 安全协议,它对 EIS 的连接进行认证和访问控制,保障 EIS 的安全。

在实现系统协议的基础上,资源适配器模块遵循以下规范:

  • 根据规范接口和系统协议,实现面向特定 EIS 系统的连接代码,连接库等;
  • 实现一个部署描述符 ra.xml(deployment descrīptor),给 J2EE 应用服务器提供所需的配置信息;
  • 所有Java类打包成 jar 文件,并和部署描述符 ra.xml 一起放在后缀为 RAR (Resource Adapter Archive) 的资源适配器文件中。这个 RAR 文件符合 jar 的打包格式,可以直接部署到 J2EE 应用服务器中。

另外用户接口(Client API)是提供给 J2EE 应用程序的 API,以便其能够访问 EIS 系统。通用用户接口(Common Client Interface)是被推荐使用的协议,资源适配器将负责实现这些接口。通过它,J2EE 应用程序可以使用统一的接口去访问各种 EIS 系统。


图2:JCA 中的系统协议和资源适配器模块结构
图2:JCA 中的系统协议和资源适配器模块结构

1.2 WebSphere Adapter 介绍

IBM WebSphere Adapter 是IBM公司开发的符合 JCA 1.5 标准的一系列资源适配器的统称。它针对不同的 EIS 系统提供不同的解决方案,使得符合 JCA 1.5 标准的 J2EE 应用程序能够和各种 EIS 系统进行方便的交互。每个 WebSphere Adapter 都是以资源适配器的形式提供,它是实现了 JCA 标准的一个组件,以 RAR (Resource Adapter Archive) 文件的形式提供给开发者使用。现在有三种类型的适配器:

  • Application Adapter: 这类适配器是针对特定的 EIS 系统来提供的,比如 WebSphere Adapter for SAP 就是为 SAP 的 ERP 系统设计的,用来访问其 ERP 系统,WebSphere Adapter forOracle是针对 Oracle 数据库提供的,用来支持各种 J2EE 应用程序访问 Oracle 数据库。
  • Technology Adapter: 这类适配器针对实现某种技术的 EIS 系统,比如本文要介绍的 WebSphere Adapter for JDBC 就是针对那些实现 JDBC 2.0 规范的数据库系统,WebSphere Adapter for JMS 针对实现 JMS 的 EIS 系统。
  • Adapter 开发工具:严格来说,这不是适配器的一种,它只是为用户开发自己的适配器提供了方便,比如 WebSphere Adapter Toolkit。

1.3 WebSphere Adapter for JDBC 介绍

WebSphere Adapter for JDBC就是符合 JCA 1.5标准的一个资源适配器,它提供了 J2EE 应用程序和支持JDBC 2.0的数据库系统沟通的桥梁。WebSphere Adapter for JDBC完全满足 JCA 的标准,被设计成可以在 WebSphere Integration Development(WID)上使用、并且在 WebSphere Process Server (WPS) 或者 WebSphere Enterprise Service Bus (ESB) 等应用服务器上运行的一个组件。它提供如下的功能:

  • 与 WPS 或 ESB 等应用服务器整合。
  • 连接服务器上的 J2EE 应用程序和支持JDBC 2.0的数据库。
  • 支持 J2EE 应用程序和数据库的数据交换。

WebSphere Adapter for JDBC 由下列组件构成:

  • JCA 的实现,用来支持应用服务器。
  • 企业元数据发现组件,可以通过这个组件来连接 EIS 产生Business Objects (BO)及其他Service Component Architecture(SCA)组件。

WebSphere Adapter for JDBC 通过 JDBC 的 API 提供对于数据库访问的两种方式:inboud 和 outbound 。在 outbound 方式下, J2EE 应用程序产生 Data Object,并将其传递给 WebSphere Adapter for JDBC 。Adapter 根据 Data Object 中指定的操作访问其连接的数据库,这些操作可以是查询单条记录、查询全部记录、创建记录、更新记录及删除记录。在 inbound 方式下,当数据库的记录改变时,数据库会产生一定的事件,这个事件连同被改变的记录的信息将会被插入到 EventStore 中,这由数据库的 trigger 或者其他方法完成。Adapter 会监测 EventStore,得到相应的一批记录。Adapter 处理这些记录以便构建 JDBC business graph,并且将这些 business graph 发送到订阅相应的数据表改变事件的应用程序,从而使应用程序获得数据库改变的通知。下图描述的是 inbound 和 outbound 对应的体系结构。


图3:WebSphere Adapter for JDBC 提供的两种操作
图3:WebSphere Adapter for JDBC 提供的两种操作




回页首


二、 使用 WebSphere Adapter for JDBC

本章将介绍一个针对于实际应用的 WebSphere Adapter for JDBC 的解决方案。在此解决方案中,我们通过一个股票管理与交易系统来展示 WebSphere Adapter for JDBC 的用法,描述了如何使用 WebSphere Adapter for JDBC 的 Inbound 和 Outbound 功能。首先介绍股票管理与交易系统的解决方案,其次介绍 WebSphere Adapter for JDBC 的用法。

2.1 场景介绍


图4:股票管理与交易系统
图4:股票管理与交易系统

上图展示的是我们提供的股票管理和交易系统的解决方案,此解决方案包括三个部分:股票交易系统、用户通知反馈系统以及监控系统。这三个子系统通过 WebSphere Enterprise Service Bus 来进行消息传递和交互。其中 Stock Interface 子系统是用 Portal 技术开发的股票管理与交易系统门户网站,包括了三个子模块:e-stock, membership 以及 admin。E-stock 表示在线股票查询以及交易功能,membership 表示用户管理功能,比如用户的信息等,admin 表示后台管理功能。Notification system 子系统表示当某支股票发生一定的变化时通知用户的功能,user notification 表示用户所购入的股票低于或者高于某个价格时,将通过手机短消息的形式通知用户。DB2 保存股票信息、用户信息、用户购买和卖出股票的详细记录。而 Monitor 子系统使用 WebSphere Monitor 来监控系统的性能。

Outbound 场景如图5所示。用户通过股票系统的门户网站登录、查询股票信息以及购入或者卖出某支股票等。门户网站通过部署在ESB上的 WebSphere Adapter for JDBC 来访问 DB2 数据库,并返回信息给用户。其中有 loadUserInfo(), getStockInfoBySearchCondition(), confirmBuy(), confirmSell()等操作。

inbound 场景如图6所示。首先管理员通过门户网站对某一股票信息作了更改,比如股票的信息等,另外股票的价格也可能受外界的影响而变化。此时DB2数据表的改动将 触发 trigger,添加事件到某一事件表中。WebSphere Adapter for JDBC 监测到这一事件,根据这一事件的来源查找受影响的用户,从而给这些用户发送短消息通知。此场景不仅包含 inbound 操作,也包含 outbound 操作,我们只把注意力放在 inbound 操作上。


图5: outbound 场景
图5: outbound 场景

图6: inbound 场景
图6: inbound 场景

2.2 如何使用 WebSphere Adapter for JDBC

下面将介绍如何在 WID 中使用 WebSphere Adapter for JDBC 来开发上述解决方案中的 outbound 和 inbound 场景。

WebSphere Adapter for JDBC 的安装过程非常简单,只要按照提示一步一步的安装就行了。安装之后的 Adapter 将以一个 rar 包的形式提供给开发者使用。因此无论本地机器还是远程机器上安装 Adapter,只要能够访问它,WID 就能通过它访问指定的数据源。首先需要在 WID 中导入 Adapter 提供的 rar 包,此时 WID 就会自动生成一个 Connector project,然后就可以在这个 connector project 的基础上创建需要的组件,比如企业服务发现组件 (Enterprise Service Discovery) 等。最后将项目部署在 ESB 或者 WPS 服务器上。下面分别描述创建 outbound 和 inbound 的项目的详细步骤。

2.2.1 构建 outbound 场景

1. 在 WID 中导入 WebSphere Adapter for JDBC 的 rar 文件。可以通过进入 Business Integration perspective 选择File->Import来启动导入向导,选择RAR file 并且指定 rar 文件所在的位置来导入 WebSphere Adapter for JDBC。如图7、8所示。此时WID将会生成一个 connector project。然后将 JDBC 驱动加入到其编译路径(Java Build Path)中,如图9所示。


图7:导入向导
图7:导入向导

图8:导入 RAR file
图8:导入 RAR file

图9:在class path 中添加 JDBC 驱动
图9:在class path中 添加 JDBC 驱动

2. 切换到 Business Integration 视图,选择New->Enterprise Service Discovery,在出现的向导里选择第一步产生的 Adapter,然后输入数据库的连接参数,选择需要操作的数据库表,确定那种类型的操作(inbound, outbound )以及具体的操作(create, update, delete, retrieve, retrieveAll),生成访问数据库的接口。对于 outbound 操作,就可以通过调用此接口提供的函数来访问数据库。

a) 新建 Enterprise Service Discovery 项目。切换到 Business Integration 视图,选择 New->Enterprise Service Discovery,点击 Next。


图10:新建 Enterprise Service Discovery
图10:新建 Enterprise Service Discovery

b) 选择第1步中新建项目的Adapter。


图11:选择第1步中产生的 Adapter
图11:选择第1步中产生的 Adapter

c) 设置数据库联接参数。


图12:设置数据库联接参数
图12:设置数据库联接参数

d) 点击 Run Query,选择需要操作的数据表。


图13:选择数据表
图13:选择数据表

e) 选择操作类型,我们选择 outbound 操作,并且选择具体的操作,比如 Create, Update 等。


图14:选择操作类型
图14:选择操作类型

f) 在出现的 artifacts 设置对话框中,新建一个 JDBCTestOutbound 模块,然后设置产生的 artifacts 参数。其中需要注意的是连接属性(connection properties)需要选择使用动态连接属性(use discovered connection properties),并且指定的 J2C Authentication Data Entry 是在 ESB 服务器或者 WPS 服务器上已经存在的 J2C 验证条目,此条目提供了访问数据库的认证,包括用户名和密码。如果 ESB 服务器或者 WPS 服务器上不存在访问指定的数据库的认证条目,则需要新建一个。新建 J2C 认证条目,需要用Web浏览方式登陆 ESB 或者 WPS 服务器管理页面,选择 Global Security->J2EE Connector Architecture (J2C) authentication data entries,选择新建并且指定用户名和密码,如图17、18所示。


图15:新建 JDBCTestOutbound 模块
图15:新建JDBCTestOutbound模块

图16:设置产生的 artifacts 参数
图16:设置产生的artifacts参数

图17:新建 J2C 认证条目
图17:新建J2C认证条目

图18:指定访问数据库的用户名和密码
图18:指定访问数据库的用户名和密码

g) 此时,Enterprise Service Discovery 向导结束。WID 为我们生成了一个 JDBCOutboundInterface 的接口,此接口包含访问数据库的指定操作。为了利用这个接口,我们需要新建一个组件 (Component),通过组件来调用这个接口提供的操作来完成具体的数据库访问。首先为这个组件定义好对外提供的接口。


图19:新建接口
图19:新建接口

图20:接口定义
图20:接口定义

接口中所使用的数据类型如下所示。









h) 新建组件并且添加这个接口。


图21:为组件添加接口
图21:为组件添加接口

i) 连接此组件和JDBCOutboundInterface接口。


图22:连接组件和接口
图22:连接组件和接口

j) 利用 WID 生成此组件的实现。此时在实现文件中你可以看到这样一段代码,此代码表示对于 JDBCOutboundInterface 的调用。


public JDBCOutboundInterface
locateService_JDBCOutboundInterfacePartner() {
return (JDBCOutboundInterface) ServiceManager.INSTANCE
.locateService("JDBCOutboundInterfacePartner");
}

然后可以用下面的代码访问数据库,实现创建数据库条目的操作。


private static final BOFactory factory = (BOFactory)
ServiceManager.INSTANCE
.locateService(AdapterConstant.BOFACTORY_PATH);

/**
* logger for log4j.
*/
private static Logger logger = Logger.getLogger(EStockImpl.class);

/**
* Comment for <code>j</code>
*/
JDBCOutboundInterface j = locateService_JDBCOutboundInterfacePartner();


//load user info from database
public DataObject loadUserInfo(String userID) throws
ServiceBusinessException {
logger.debug("load user info start...");
logger.debug("user ID: " + userID);

//create dataobject used in retrieving database
DataObject dbuserbg = factory.create(
"http://StockLibrary/DataTypes/db2inst1userbg",
"Db2inst1UserBG");
DataObject dbuser = factory.create(
"http://StockLibrary/DataTypes/db2inst1user",
"Db2inst1User");

//create data object returned to invoker.
DataObject user = factory
.create("http://StockLibrary/DataTypes", "User");

//retrieve database with interface generated by adapter
dbuser.setString("userid", userID);
dbuserbg.setString("verb", null);
dbuserbg.setDataObject("Db2inst1User", dbuser);
try {
dbuserbg = j.retrieveUser(dbuserbg);
} catch (Exception e) {
throw new
ServiceBusinessException(CodeSystem.EM_NO_USER_FOUND);
}
dbuser = dbuserbg.getDataObject("Db2inst1User");
user.setString("userID", dbuser.getString("userid"));
user.setString("userType", dbuser.getString("usertype"));
user.setString("mobilephoneNumber",
dbuser.getString("mobilephoneNumber"));
user.setString("preferedLanguage",
dbuser.getString("preferedLanguage "));

String userName = dbuser.getString("namegboobject");
try{
NameObject newNameObject = NameObject.parse(userName);
String firstName =
newNameObject.getName(NameField.NAME_FIELD_ID_FIRST_NAME);
logger.debug(firstName);
user.setString("userName", firstName);
}catch(NameException e){
//e.printStackTrace();
logger.error("can't load user name");
}
logger.debug("load user info successfully...");
return user;
}


//确认购入股票信息
public String confirmBuy(DataObject stock, int quantity, String
userID) throws ServiceBusinessException {
String retval = CodeSystem.SUCCESS;
String stockID = stock.getString("stockID");
DataObject dbstockbg = factory
.create(
"http://StockLibrary/DataTypes/db2inst1stockbg",
"Db2inst1StockBG");
DataObject dbstock = factory
.create(
"http://StockLibrary/DataTypes/db2inst1stock",
"Db2inst1Stock");
DataObject dbohbg = factory.create(
"http://StockLibrary/DataTypes/db2inst1operationhistorybg",
"Db2inst1OperationhistoryBG");
DataObject dboh= factory.create(
"http://StockLibrary/DataTypes/db2inst1operationhistory",
" Db2inst1Operationhistory");
try {
dbstock.setLong("stockid", Long.parseLong(stockID));
dbstockbg.setString("verb", null);
dbstockbg.setDataObject("Db2inst1Stock", dbstock);
dbstockbg = j.retrieveStock(dbstockbg);
dbstock = dbstockbg.getDataObject("Db2inst1Stock");
double price = dbstock.getString("price");
dbohbg.setString("verb", "Create");
dboh.setString("userID", userID);
dboh.setString("stockID",stockID);
dboh.setString("buyingQuantity",quantity);
dboh.setString("buyingPrice",price);
dboh.setString("quantity",quantity);
dbohbg.setDataObject("Db2Operationhistory", dboh);
j.updateOperationhistory(dbohbg);

} catch (NumberFormatException e) {
// TODO Auto-generated catch block
retval = CodeSystem.EM_GENERAL;
throw new ServiceBusinessException(CodeSystem.EM_NOETICKET);
} catch (Exception e) {
// TODO Auto-generated catch block
retval = CodeSystem.DB_RESULT_EXCEPTION;
throw new
ServiceBusinessException(CodeSystem.DB_RESULT_EXCEPTION);
}

return retval;
}

k) 为了能够调用实现的这个组件,需要将其以 Web Service 的形式导出,并且选择 soap/http 方式。至此 outbound 类型的 Adapter 项目实现完毕。


图23:导出为 Web Services
图23:导出为Web Services

图24:选择 Web Services传输方式
图24:选择Web Services传输方式

2.2.2 构建 inbound 场景

我们来看一下 inbound 类型的 Adapter 的实现方式。新建 Enterprise Service Discovery 以及设置连接参数、选择数据表的设置方式与 outbound 类型相同。不同的操作步骤从2 e)选择操作类型开始。另外 inbound 需要在数据库中创建一个事件表和 trigger 来辅助事件的转发。下面来看详细步骤。

e) 创建事件表和 trigger


CREATE TABLE WBIA_JDBC_EVENTSTORE(
EVENT_ID INT GENERATED ALWAYS AS IDENTITY
(START WITH 1, INCREMENT BY 1, NO CACHE ) NOT NULL ,
OBJECT_KEY INT NOT NULL,
OBJECT_NAME VARCHAR(40) NOT NULL ,
OBJECT_FUNCTION VARCHAR(40) NOT NULL,

CREATE TRIGGER EVENT_CREATE AFTER UPDATE ON STOCK
REFERENCING NEW AS N FOR EACH ROW MODE DB2SQL
INSERT INTO wbia_jdbc_eventstore (object_key, object_name,
object_function,) VALUES (N.stockID, 'Db2inst1StockBG', 'Update');

f) 选择操作类型,我们选择 inbound 操作,并且选择具体的操作,比如Create, Update等。


图25:选择操作类型
图25:选择操作类型

g) 在出现的 artifacts 设置对话框中,新建一个 JDBCTesInbound 模块,然后设置产生的 artifacts 参数。同 outbound 类型一样,连接属性(connection properties)需要选择使用动态连接属性(use discovered connection properties),但此时 inbound 类型并不需要 J2C Authentication Data Entry。不同的是需要指定事件表和相应的排序字段,以便 Adapter 能够监测这个事件表,从而确定事件的发生。


图26:设置产生的 artifacts 参数
图26:设置产生的 artifacts 参数

h) 此时,Enterprise Service Discovery 向导结束。WID 为我们生成了一个 JDBCInboundInterface 的接口,此接口包含当指定的数据表改变时将要触发的函数。为了利用这个接口,我们需要新建一个组件 (Component),通过组件来利用这个接口提供的操作来对数据库的改变进行反应。首先新建接口,并将接口与组件连接起来。


图27:新建接口并连接
图27:新建接口并连接

然后利用 WID 生成此组件的实现。此时在实现文件中你可以看到这样一段代码,此代码表示当 Operationhistory 的条目发生改变时将要触发的动作。


public void updateDb2inst1Stock(
DataObject updateDb2inst1StockInput) {
//TODO Needs to be implemented.
}

i) 为上面这个函数添加代码如下:



public void updateDb2inst1Stock (DataObject
updateDb2inst1StockInput) {
System.out.println("stock info changed and notify user
start...");
//get data changed
DataObject dataObject = updateDb2inst1StockInput
.getDataObject("Db2inst1Stock");
System.out.println(updateDb2inst1StockInput
.getString("verb"));
System.out.println("updated stock: "
+ dataObject.getString("stockID"));
String price= dataObject.getString("price");
if (price < AdapterConstant.LOW_PRICE || price >
AdapterConstant.HIGH_PRICE) {
//get user list by stock id
List userList = getUserListByStock(
dataObject.getString("stockID"));

//call service on WPS to notify user
NotifyFFBP notifyService =
locateService_NotifyFFBPPartner();
BOFactory factory = (BOFactory)
ServiceManager.INSTANCE.locateService(
"com/ibm/websphere/bo/BOFactory");
DataObject message =
factory.create("http://StockLibrary/DataTypes",
"ShortMessage");
message.setString("price", price);
message.setString("stockID", stockID);
message.setList("userList", userList);

notifyService.sendSMS(message);
}
System.out.println("notify user end...");
}

因为 inbound 操作是由数据库发起的,利用数据表的改变去调用相应的函数,因此 inbound 操作不需要导出为 Web services。

2.2.3 部署项目

a) 将生成的 inbound 或者 outbound 项目打包为 EAR 。


图28:导出为 EAR 文件
图28:导出为 EAR 文件

b) 使用浏览器登陆ESB或者WPS服务器管理页面,选择 Application->Install new application,选择相应的 EAR 文件,如图24所示。然后点击 Next 或者 Finish 一直到应用程序安装完毕。


图29:在服务器上部署应用程序
图29:在服务器上部署应用程序

c) 将使用的JDBC驱动拷贝到ESB或者WPS安装目录的lib文件下,<installation of ESB or WPS\lib>,然后在安装的应用程序列表中,启动刚刚安装的程序。

至此,我们已经介绍了如何使用 WID 和 WebSphere Adapter for JDBC开发 inbound 和 outbound 类型的应用程序,并且介绍了如何部署这些程序。





回页首


三、 注意事项

在使用 WebSphere Adapter for JDBC 的过程中,我们遇到了一些比较常见并且容易出错的地方,这可能是由于 WebSphere Adapter for JDBC 正处于开发测试阶段,相信随着 WebSphere Adapter for JDBC 的进一步开发和测试,这样的问题会越来越少。下面我们就一一介绍这些问题,希望能够帮助读者解决在使用 WebSphere Adapter for JDBC 的过程中出现的一些困难。

3.1 有关JDBC驱动

使用 JDBC 驱动的建议:使用 db2jcc.jar 中的 JDBC 驱动,不要使用 db2java.zip 中的 JDBC 驱动。

虽 然 db2jcc.jar 和 db2java.zip 都提供了 DB2 的 JDBC 驱动,但我们在使用 db2java.zip 中的 COM.ibm.db2.jdbc.app.DB2Driver 时发现这个 JDBC 驱动和 WebSphere Adapter for JDBC 或者 ESB 服务器存在着一定的兼容问题。我们使用这个 JDBC 驱动分别开发了 outbound 和 inbound 类型的项目,如下图所示:


图30:使用 db2java.zip 中的 JDBC 驱动
图30:使用 db2java.zip 中的 JDBC 驱动

这些项目能够成功的部署到 WID 内嵌的 ESB 测试环境中,但在将这些项目移植到单独安装的 ESB 服务器时却出现了问题。在启动这些项目时,项目无法启动或者无法调用,并且ESB服务器出现了 No suitable Driver 这种异常,如下图所示:


图31:ESB服务器的 No suitable driver 异常
图31:ESB服务器的 No suitable driver 异常

起初,我们以为是 JDBC 驱动可能存在着冲突的问题,也就是在 ESB 服务器的类路径下存在着两个同样的 JDBC 驱动,因此我们将拷贝到<esb installation\lib>下的 db2java.zip 删除,重启 ESB 服务器,并重新尝试启动或调用这些项目,但项目仍无法启动或调用,这时ESB服务器出现了 ClassNotFound 异常,如下图所示:


图32:ESB 服务器的 ClassNotFound 异常
图32:ESB服务器的ClassNotFound异常

因此我们推断应该是 db2java.zip 与 WebSphere Adapter for JDBC 或者 ESB 服务器的兼容问题,这些问题在使用 db2jcc.jar 中的 JDBC 驱动时得到了解决。

3.2 有关数据库设计

数据库字段类型的选择建议:对于表示日期和时间的字段,不要使用 Timestamp, Date 数据类型。

数 据库中可能会需要保存时间和日期的字段,最方便的做法就是将这些字段的类型设置为 Timestamp, Date。但这样做在使用 WebSphere Adapter 时会出现问题。在生成的 outbound 项目中,我们试图利用 WebSphere Adapter 为我们生成的访问数据库的接口来访问数据库并取出这些时间字段,但令人惊讶的是在取出的时间变量中,我们只得到了日期值,而没有时间信息。通过进一步的测 试和观察发现,问题在于 WebSphere Adapter for JDBC v6.0.0.1 将数据库中 Timestamp, Date 类型转换成了 java 中的 java.sql.Date 类。在 J2SE 的 API 文档中对于 java.sql.Date 中的 getHours 函数有这样一段描述:This method is deprecated and should not be used becauseSQLDate values do not have a time component. 这个描述说明了 java.sql.Date 类并不包含时间信息,因此在从数据库中取出时间字段转换为 java.sql.Date 时,时间信息已经丢失了。因此在涉及到需要保存时间信息时,在数据库中不要使用 Timestamp, Date 类型。建议使用字符串来保存这些信息,在程序中作转换。

数据库设计的建议:尽量少的改动数据库。对于数据库中的每张数据表, WebSphere Adapter for JDBC 都将其转换为一种数据类型,这种数据类型的每个字段都与数据表中的字段一一对应。但如果我们改动了数据表中的某个字段,比如更改了这个字段的类型或者名 字,WebSphere Adapter for JDBC 或者 WID 并不会自动将与这个数据表对应的数据类型中的字段改变,你需要手动去修改它。但不幸的是,WID 也存在着一定的问题,它对于数据类型的改变支持的不好。为了能使数据类型的改变生效,需要删除临时文件并且重新编译项目。但这些工作并不能保证数据类型的 改变一定能成功,更糟的情况是你需要重建项目,然后把原来项目的实现一行行的拷贝到新项目中去。

3.3 关于模糊查询

因 为 WebSphere Adapter for JDBC 还不成熟完善,因此在使用它时可能会遇到一些限制。其中之一就是对于数据表的复杂查询的限制。WebSphere Adapter for JDBC 只能使用精确的查询语句,也就是字段要么不加限制,要么等于某个值,它不支持〈、〉、?、*等模糊查询。因为需要通过编程来使用 WebSphere Adapter for JDBC 提供的查询功能,而在编程中,只能使用 DataObject 类型的 set 函数来设置查询条件,set 函数并不支持模糊的设置条件,因此 WebSphere Adapter for JDBC 只支持精确查询。





回页首


四、 结论

本文通过我们实现的股票管理与交易系统的场景介绍了如何使用 WebSphere Adapter for JDBC 的 inbound 和 outbound 功能,并且指出在实际的使用过程中所碰到的问题,针对这些问题,提出了相应的解决或者妥协方法,希望能够减少读者在使用 WebSphere Adapter for JDBC 时所付出的努力和代价。



参考资料

  1. J2EE Connector Architecture, Version 1.5 specification.http:// java.sun.com/j2ee/connector/.
  2. Introduction to the J2EE Connector Architecture.http://www.ibm.com/developerworks/edu/j-dw-javajca-i.html.
  3. Redbook for WebSphere Adapter Development.http://www.redbooks.ibm.com/abstracts/sg246387.html.
  4. Whitepaper for Enterprise Metadata Discovery.http://www.ibm.com/developerworks/java/library/j-emd/.

TAG: IBM

 

评分:0

我来说两句

Open Toolbar