技术开发 频道

开源ETL工具kettle系列之在应用程序中集成

连接资源库
连接资源库使用的是connectToRepository()方法,先取得RepositoriesMeta对象,然后根据你在setting.xml文件里面定义的repository的名字来连接对应的repository.理论上来说我们一般都只使用一个repository ,但如果在产品中需要使用多个repository的话,你需要自己配置多个repository的名字和对应的用户名和密码。只列出几行关键代码,
repositoriesMeta = new RepositoriesMeta(logWriter);
repositoriesMeta.readData(); // 从$HOME/.kettle/repositories.xml 读数据.
repositoryMeta = repositoriesMeta.findRepository(repositoryName);
repository = new Repository(logWriter, repositoryMeta, userInfo);
userInfo = new UserInfo(repository, username, password);

从资源库读取Trans
连接到资源库之后自然是想办法读取数据库的表,把里面的记录转换成为Trans 对象,使用的是loadTransformFromRepository,这个方法的函数原型需要解释一下:
TransMetaloadTransformFromRepository(String directoryName, String transformationName, Repository repository,LogWriter logWriter)
第一个参数String directoryName 代表是你储存转换的目录,当你使用kettle 图形界面的时候,点击repository菜单的explorer repository , 你会发现你所有的东西都是存储在一个虚拟的类似与目录结构的地方,其中包括database connections , transformations , job , users 等,所以你需要的是指定你连接的目录位置,你也可以在目录里面再创建目录。
String transformationName 自然指的就是你转换的名字.
Repository repository 指的是你连接的资源库。
LogWriter logWriter 指定你的日志输出,这个log 指的是你kettle 转换的日志输出,不是应用程序本身的输出。
读取TransMeta的步骤也相对比较简单
repositoryDirectory=repository.getDirectoryTree().findDirectory(directoryName);
transMeta = new TransMeta(repository, transformationName, repositoryDirectory);

从资源库读取Job
从资源库读取Job跟Trans 的步骤基本是一样的,同样需要指定你存储Job的目录位置.
JobMeta loadJobFromRepository(String directoryName, String jobName,
Repository repository, LogWriter logWriter)

读取结果集
一般Job都是不会返回任何结果集的,大部分Trans也不会返回结果集,应为结果集一般都会直接从一个数据库到另一个数据库了,但是如果你需要返回转换的结果集,那么这一小结将会向你解释如何从一个Trans里面读取这些结果集
首先,你需要一个容纳Result的容器,就是类似与JDBC里面的resultSet, resultSet当然会有一个resultSetMetadata跟它相关联,在本文所举的实例中,使用的是pentaho私有的memoryResultSet,
你可以不用关心它的细节,并且它的类型正如它的名字一样是存在与Memory的,所以它不能被持久化,这个里面储存的是一个二维的Object数组,里面的数据就是从kettle转化之后来的。
要从kettle的转换中读取结果集,要实现RowListener 接口,Row 是kettle里面表示一行数据的一个类,RowListener 自然是指在转换数据转换的时候发生的事件,它有三个方法需要实现,
void rowReadEvent(Row)
void rowWrittenEvent(Row)
void errorRowWrittenEvent(Row)
分别对应读数据时的事件,写数据事的时间,出错时的时间,我们需要取得结果集,所以只需要实现rowWrittenEvent(Row)就可以了,Row对象是通过TransMeta取得的,
Row row = transMeta.getStepFields(stepName);
下面给出具体实现取Row转换成resultSet的代码:
Object pentahoRow[] = new Object[results.getColumnCount()];
    for (int columnNo = 0; columnNo < results.getColumnCount(); columnNo++) {
      Value value = row.getValue(columnNo);
      switch (value.getType()) {
        case Value.VALUE_TYPE_BIGNUMBER:
          pentahoRow[columnNo] = value.getBigNumber();
          break;
    ........

results.addRow(pentahoRow);
默认的数据类型是String 类型(在省略部分).
整个代码最重要的一行是Value value = row.getValue(columnNo);
这是真正取得实际数据的一行。有时候你会觉得实现一个resultSet比较麻烦,尤其是你还要实现相关的resultSetMetaData,怎么把数据转换成你自己的类型,你大可以就用一个List of List 来实现,里面的List 就代表Row 的对应数据,外面一层List 就是result , 整个代码会简单一些,当然,你要自己知道最后这个List怎么用.

本文有意隐藏了一些跟pentaho有关的细节,比如validateSystemSettings(),init(),validateAction()方法,这些都是pentaho私有的,有些方法比如rowWrittenEvent(Row) 是用来取结果集的,但是很多时候我们不需要取转换的结果集,文中很多代码都只列出主要的部分,省略一些判断,调试,log部分的代码,大家可以自己下载这些代码来研究,
本文并没有给出一个可以独立运行的示例,因为这个示例一定会太过于简单(不超过15行代码),但是却并不能考虑到各种情况,连接资源库还是文件,运行转换还是Job ,metadata怎么得来的,需不需要转换之后的结果。
关于在本文一开始提到的使用kettle的两种方式,对于第二种使用方式:使用完全编程的方式来运行转换,其实它的与第一种方式的区别就好像一个用设计器来写xml文件,一个用纯手工方式写xml文件(用代码的xml),大家可以参考官方网站上的一段示例代码,地址如下:
http://kettle.pentaho.org/downloads/api.php

相关文章:
开源ETL工具kettle系列之建立缓慢增长维
http://tech.cms.it168.com/db/2008-03-21/200803211716994.shtml
开源ETL工具kettle系列之动态转换
http://tech.cms.it168.com/o/2008-03-17/200803171550713.shtml
开源ETL工具kettle系列之增量更新设计技巧
http://tech.cms.it168.com/db/2008-03-21/200803211924754.shtml
开源ETL工具kettle系列之在应用程序中集成
http://tech.it168.com/db/2008-03-19/200803191510476.shtml
开源ETL工具kettle系列之常见问题
http://tech.it168.com/db/2008-03-19/200803191501671.shtml
0
相关文章