在数据清洗转换中,常见的字典翻译,如性别在原表中是1(男)、2(女)等,类似还有很多较大的字典需要翻译,若同一个表中有很多个字典需要翻译,采用【数据库查询】方式翻译的话效率就会相当低下。

  这里采用java代码来翻译,初始化时将相关字典加载到内存中,此后就不需要再查询数据库了,然后每条记录进来就翻译各个字典,其实很简单,只是【java代码】这个控件限制较多,不支持泛型、this并不是步骤本身、能使用的方法都列在了左侧,使用起来不是很方便。关于字典翻译这个事,其实写一个专门的控件也不难,也是很不错的一个主意,只是没有真正完整的写个一个控件(后台实现和ui部分等),要写的话比较耗时,暂时就采用java代码实现,有时间可以考虑写这么个控件。

  算了废话太多,测试转换如下图

  自定义常量就是模拟了几条数据,你可以直接传递要翻译的数据,写日志就是看看翻译结果,【java代码】中的代码如下:

  1. import java.util.Arrays;
  2. import java.util.List;
  3. import java.util.HashMap;
  4. import java.util.Map;
  5. import org.pentaho.di.core.database.Database;
  6. import org.pentaho.di.core.database.DatabaseMeta;
  7. import org.pentaho.di.repository.Repository;
  8. import org.pentaho.di.core.Const;
  9.  
  10. public boolean processRow(StepMetaInterface smi, StepDataInterface sdi) throws KettleException
  11. {
  12. if (first){
  13. first = false;
  14.  
  15. /* TODO: Your code here. (Using info fields)
  16.  
  17. FieldHelper infoField = get(Fields.Info, "info_field_name");
  18.  
  19. RowSet infoStream = findInfoRowSet("info_stream_tag");
  20.  
  21. Object[] infoRow = null;
  22.  
  23. int infoRowCount = 0;
  24.  
  25. // Read all rows from info step before calling getRow() method, which returns first row from any
  26. // input rowset. As rowMeta for info and input steps varies getRow() can lead to errors.
  27. while((infoRow = getRowFrom(infoStream)) != null){
  28.  
  29. // do something with info data
  30. infoRowCount++;
  31. }
  32. */
  33. }
  34.  
  35. Object[] r = getRow();
  36.  
  37. if (r == null) {
  38. setOutputDone();
  39. return false;
  40. }
  41. //获取要翻译字典的代码
  42. String kkdm = get(Fields.In, "kkdm").getString(r);
  43. String cllx = get(Fields.In, "cllx").getString(r);
  44.  
  45. // It is always safest to call createOutputRow() to ensure that your output row's Object[] is large
  46. // enough to handle any new fields you are creating in this step.
  47. r = createOutputRow(r, data.outputRowMeta.size());
  48. //翻译字典并设置到输出字段中
  49. get(Fields.Out, "kkmc").setValue(r, kkzdMap.get(kkdm));
  50. get(Fields.Out, "cxmc").setValue(r, cxzdMap.get(cllx));
  51.  
  52. /* TODO: Your code here. (See Sample)
  53.  
  54. // Get the value from an input field
  55. String foobar = get(Fields.In, "a_fieldname").getString(r);
  56.  
  57. foobar += "bar";
  58.  
  59. // Set a value in a new output field
  60. get(Fields.Out, "output_fieldname").setValue(r, foobar);
  61.  
  62. */
  63. // Send the row on to the next step.
  64. putRow(data.outputRowMeta, r);
  65.  
  66. return true;
  67. }
  68.  
  69. //定义字典缓存Map
  70. public static Map cxzdMap = new HashMap();
  71. public static Map kkzdMap = new HashMap();
  72. public boolean init(StepMetaInterface stepMetaInterface, StepDataInterface stepDataInterface)
  73. {
  74. try {
  75. //连接数据库,pg_test是数据库名称,在左侧db连接处创建
  76. DatabaseMeta dbmeta = DatabaseMeta.findDatabase(this.getTrans().getRepository().readDatabases(), "pg_test");
  77. Database zddb = new Database(this.getTrans(),dbmeta);
  78. logBasic(zddb.getObjectName());
  79. zddb.shareVariablesWith( this.getTrans() );
  80. zddb.setQueryLimit( Const.toInt( this.getTrans().environmentSubstitute( "100" ), 0 ) );
  81.  
  82. try {
  83.  
  84. if ( getTransMeta().isUsingUniqueConnections() ) {
  85. synchronized ( getTrans() ) {
  86. zddb.connect( getTrans().getTransactionId(), "zdfy" );
  87. logBasic(zddb.getObjectId().toString());
  88. }
  89. } else {
  90. zddb.connect( getTrans().getTransactionId(), null );
  91. }
  92. }catch ( KettleException e ) {
  93. logError( "An error occurred, processing will be stopped: " + e.getMessage() );
  94. setErrors( 1 );
  95. stopAll();
  96. }
  97. if ( dbmeta.isRequiringTransactionsOnQueries() ) {
  98. zddb.setCommit( 100 );
  99. }
  100. logBasic(Arrays.asList(zddb.getTablenames()).toString());
  101. //查询字典表,获取字典数据本缓存到对应Map中
  102. List list = zddb.getRows("SELECT * from t_cxzd", 1000);
  103. for(int i=0;i<list.size();i++){
  104. Object[] objs = (Object[]) list.get(i);
  105. cxzdMap.put(objs[0].toString(), objs[1].toString());
  106. }
  107. logBasic(cxzdMap.entrySet().toString());
  108. list = zddb.getRows("SELECT * from t_kkzd", 1000);
  109. for(int i=0;i<list.size();i++){
  110. Object[] objs = (Object[]) list.get(i);
  111. kkzdMap.put(objs[0].toString(), objs[1].toString());
  112. }
  113. logBasic(kkzdMap.entrySet().toString());
  114. zddb.disconnect();
  115. } catch (KettleException e1) {
  116. logError("获取数据库失败", e1);
  117. }
  118. return parent.initImpl(stepMetaInterface, stepDataInterface);
  119.  
  120. }

kettle系列-6.kettle实现多字段字典快速翻译的更多相关文章

  1. kettle系列-1.kettle源码获取与运行

    第一次写博客,心里有点小激动,肯定有很多需要改进的地方,望海涵. kettle算是我相对较为深入研究过的开源软件了,也是我最喜欢的开源软件之一,它可以完成工作中很多体力劳动,在ETL数据抽取方面得到了 ...

  2. kettle系列-[KettleUtil]kettle插件,类似kettle的自定义java类控件

    该kettle插件功能类似kettle现有的定义java类插件,自定java类插件主要是支持在kettle中直接编写java代码实现自定特殊功能,而本控件主要是将自定义代码转移到jar包,就是说自定义 ...

  3. kettle系列-5.kettle实现二进制文件迁移

    本文就是分享下二进制文件(图片.txt文件等)在oracle和文件系统间的传输的转换示例. 转换示例如下图: 示例本身较简单,但很多人应该还是不太清楚怎么做,很多时候都是上网搜索,网上有关的就是通过j ...

  4. kettle系列-4.kettle定制化开发工具类

    要说的话这个工具类还是比较简单的,每个方法体都比较小,但用起来还是可以的,把开发中一些常用的步骤封装了下,不用去kettle源码中找相关操作的具体实现了. 算了废话不多了,直接上重点,代码如下: im ...

  5. kettle系列-3.kettle读取数据库资源库很慢的优化

    环境:windows7,jvm内存设置14G,kettle5.1后来升级到5.4,oracle作为资源库. 问题背景:我们通过web页面管理kettle的job运行,这只是一个管理界面,即使web项目 ...

  6. kettle系列-2.kettle源码结构分析

    kettle是一个开源产品,产品本身设计是很优秀的,代码应该是很多开源爱好者用业余时间贡献的,代码整体结构还是比较容易理解的,但具体到每一个控件内部就因人而异了,感觉还是挺复杂的,肯定别人考虑得比较全 ...

  7. kettle系列-我的开源kettle调度、管理平台[kettle-manager]介绍

    kettle管理工具 专门为kettle这款优秀的ETL工具开发的web端调度.管理工具. 新版本 项目简介 kettle作为非常优秀的开源ETL工具得到了非常广泛的使用,一般的使用的都是使用客户端操 ...

  8. 开源ETL工具kettle系列之常见问题

    开源ETL工具kettle系列之常见问题 摘要:本文主要介绍使用kettle设计一些ETL任务时一些常见问题,这些问题大部分都不在官方FAQ上,你可以在kettle的论坛上找到一些问题的答案 1. J ...

  9. kettle系列一之eclipse开发

    1.引言 最近公司开始一个etl项目,底层结合开源的kettle进行开发.那么学习kettle势在必行,kettle的使用在这里就不用介绍了,网上有很多的资料.例如:kettle中文社区,我们在这里主 ...

随机推荐

  1. PHP进程通信基础——shmop 、sem系列函数使用

    PHP进程通信基础--shmop .sem系列函数使用 进程通信的原理就是在系统中开辟出一个共享区域,不管是管道也好,还是共享内存,都是这个原理.如果心中有了这个概念,就会很方便去理解代码.由于官网上 ...

  2. BZOJ1492: [NOI2007]货币兑换Cash

    设$x_j$,$y_j$为第$j$天能买的A,B券数量,$f_i$为第$i$天的最大收益.$f_i=\max_{1\le j<i}a_ix_j+b_iy_j$,最大化$f_i$即找一个点$(x_ ...

  3. 【辅助远程连接,可穿防火墙、NAT】一次 TeamViewer 的安装与测试

    背景: 应课程老师要求帮助某化学老师维修机器(高性能电脑),并解决老师的若干问题,在解决硬件问题(上网问题:多个网络接口)之后,化学老师提出需要远程链接到该机器,试询问之前如何实现,化学老师推荐Tea ...

  4. Android SDK升级后报错error when loading the sdk 发现了元素 d:skin 开头无效内容

    把错误位置的devices.xml这个文件删除,再把sdk里面tools\lib下的这个文件拷贝到你删除的那个文件夹里,重启eclipse

  5. setTimeout 和 setInterval 的区别

    setTimeout (表达式,延时时间)setInterval(表达式,交互时间)延时时间/交互时间是以豪秒为单位的(1000ms=1s) setTimeout   在执行时,是在载入后延迟指定时间 ...

  6. ActiveMQ中的Destination高级特性(一)

    ---------------------------------------------------------------------------------------- Destination ...

  7. Unity3D 动态改变地形

    直接获取TerrainData进行修改即可 using System.Collections; using UnityEngine; using UnityEditor; public class D ...

  8. REDHAT一总复习1 禁用颜色

    使用man page 研究如何在输出中禁用颜色.将ls命令的相关选项放到server上的文本文件 /home/student/lscolor.txt中. 1. 在ls(l) man page中查询相关 ...

  9. Linux各个目录的作用及内容

    1)根目录“/”    根目录位于目录结构的最顶层,用斜线(/)表示,类似于Windows操作系统的“C:\“,包含Fedora操作系统中所有的目录和文件. 2)/bin    /bin 目录又称为二 ...

  10. IP分片详解

    IP分片是网络上传输IP报文的一种技术手段.IP协议在传输数据包时,将数据报文分为若干分片进行传输,并在目标系统中进行重组.不同的链路类型规定有不同最大长度的链路层数据帧,称为链路层MTU(最大传输单 ...