数据库操作
配置MB的用户数据库
前面已经讲了在创建MB运行时实例时,配置数据库的基本过程了,但那里所指的数据库是MB自己运行时需要的数据库,用来存放诸如broker、执行组、消息流等的信息,而现在开发的企业应用程序,几乎没有不用到数据库来存放业务数据的,所以这里主要讲述如何配置“用户数据库”,也即你的应用程序使用的数据库。
下面以MB 6.1 + Oracle 10g 为例,介绍配置过程
一、 ODBC数据源
MB是通过ODBC来操作数据库的,因此首先要配置好操作系统本身的ODBC数据源。Windows中配置ODBC很容易,在此不赘述细节。需要注意的是,选择Oracle数据源驱动时,一定要选择下图所示的MB自带的Oracle驱动
我在创建ODBC时,一开始没有在本机安装Oracle,结果ODBC无法使用,报告“由于系统错误126,驱动程序无法加载”,问了IBM的技术支持也没有答案,后来干脆在本机安装了一个Oracle(不必运行),问题就解决了,估计MB自带的Oracle驱动还是要调用Oracle本身的一些库的。我对Oracle本身基本不懂,具体用到了哪些库也不清楚,就先这么用着了。
二、 数据库设置
这里顺手提一下Oracle本身的设置。当你新建了Oracle的ODBC数据源后,会发现数据源设置里面,没有IP和端口设置。我在网上搜了一下,最简单的方法是直接修改Oracle的tnsnames.ora文件,这个文件位于: $oracle_root/product/ 10.1.0 /db_1/NETWORK/ADMIN/tnsnames.ora 路径下,可以用记事本打开编辑。里面本身已经有样例了,参照着改很容易
三、 消息流节点
MB中能和数据库打交道的节点有很多,包括filter、compute,和专门的数据库节点,如下图:
基本上,凡是属性里面可以设置“数据源”的节点,都可以操作数据库。使用方法很简单,直接在“数据源”属性中填入操作系统的相应ODBC数据源名称即可。
四、 代理broker的设置
这是最后一处要设置的地方。前面的tns文件解决了ip和端口的问题,但是数据源本身的用户名和密码在消息流中并没有提及,其实这是通过MB的一个命令来设置的,格式如下:
mqsisetdbparms brokerName -n dataSourceName [-u dataSourceUserId] -p dataSourcePassword
具体用法可以输入 mqsisetdbparms /h 获得参考
配置完以上内容后,运行消息流应该不会有数据库连接的异常了。假如配置不正确,会在运行到使用了“数据源”的节点处抛出ODBC的一些异常
在WMBT中创建数据库项目
以上做的工作可以确保消息流能够正确操作用户数据库,但是当你在WMBT中编写SQL语句时,会出现很多警告,内容一般是“无法解析数据库表引用:某字段”。虽然不影响运行,但看着总是不太爽。
出现警告的原因很简单,你没有告诉WMBT你需要用到的数据库表的结构是什么,所以WMBT很尽职地告诉你可能有问题,我们只需引入数据库的定义,即可消除这些警告。
首先,打开“数据库资源管理器”视图,新建一个JDBC连接,和其他EclipseIDE类似,配置好相关参数即可。
在WMBT中新建一个“数据库定义”,向导会让你顺便创建一个“数据库设计项目”,你可以通过刚刚创建的JDBC连接,选择一个数据库,即可。
这时你会发现ESQL代码中那些烦人的提示已经消失了。
在ESQL中编写SQL语句
ESQL中使用SQL和一般的SQL语句基本一致,除了在指定哪个数据表的时候,要用类似下面的语法:
SELECT FROM Database.SchemaName.TableName
其中的“Database”是关键字,一定要有的,表示从数据库中读取,这是因为ESQL中不单可以操作数据库,还可以对逻辑树、数组对象使用select、delete等SQL语法,“Database”起到标识的作用。
给出这样一条语句:
set LocalEnvironment.temp[] = select * from Database.TEST.example
假设example有id和info两个字段,共三条记录,那么执行后的结果是LocalEnvironment 树下面产生三个temp元素,每个元素都包含一个id和info子元素,对应数据库的记录。
select返回的都是数组类型,因此不能set LocalEnvironment.temp = select ….,那样会在打包时报错,一定要标明是数组
此外,像上面那样直接书写SQL语句并赋值给一个数组变量,MB会在编译和执行期间检查SQL语法是否合格,这个特性虽然很有用,但有时候也会适得其反,比如要在Oracle使用序列来实现主键自增时,insert语句要写成:
insert into example (id,info) VALUES ( SEQ_EXAMPLE.nextval , ‘xxxxx’)
这里 SEQ_EXAMPLE 是序列的名称。而在 MB 里面这样会保存,提示找不到 SEQ_EXAMPLE 这个对象的定义。解决方法是使用 ESQL 的 PASSTHRU 函数,这个函数直接将 SQL 语句发送给数据库去解析执行,就可以绕开 MB 的检查。