kettle单转换实现分页查询

1、转换简介

kettle的转换是数据流,比如我们第一个节点叫做生成数据,生成10条数据,那么后面的节点都会执行10次。如果第一个节点生成记录后面跟另一个JS节点,在JS节点又通过putrow 加了2条数据,那么数据集总共会有3条数据,JS节点执行一次,但是JS后的节点会执行3次。

2、实现思路

借助本文章节1中的转换特性,我们比如我们设计一个分页查询入库就可以分为以下几个步骤:

  • 生成所需数据 在这里我们可以定义一条数据,确保后面节点可以运行。在这个步骤我们定义2个变量(total,page和pageSize)
  • 表输入节点 用于查询总数
  • JS节点,用于根据总数和每页多少条生成页码array
javascript 复制代码
// 必须total有值的才去计算,我们自己生成的记录那个不处理
if(total){
var page_size = 10;
var total_count = total;
var totalPages = parseInt(total_count / page_size);
if (total_count % page_size > 0) totalPages++;

for (var i = 1; i <= totalPages; i++) {
    // 输出每一页的页码
    putRow( [parseInt(i), page_size] ); 
}
}
  • 经过JS节点后,实际流数据除了我们自己造的那条,数据库里查询出来的那条,还加了很多条进去,就是我们的分页数据
  • 接下来通过字段选择值/选择改名值 插件做数据类型转换,因为js只能输出double类型的变量
  • 然后跟一个switch case 让pagesize为空的进写日志步骤,其他的进默认步骤
  • 在默认步骤中我们能拿到page和pageSize都不是空的数据 走后面正常逻辑就行了,你是htttp调用接口也好,你是分页查数据库也好都行

下面给大家一个KTR代码,大家复制后另存为.ktr用kettle打开就行了。是上面那个实现的一个简单版本的demo。

XML 复制代码
<?xml version="1.0" encoding="UTF-8"?>

<transformation>
  <info>
    <name>分页查询单转换实现</name>
    <description/>
    <extended_description/>
    <trans_version/>
    <trans_type>Normal</trans_type>
    <trans_status>0</trans_status>
    <directory>/</directory>
    <parameters>
    </parameters>
    <log>
      <trans-log-table>
        <connection/>
        <schema/>
        <table/>
        <size_limit_lines/>
        <interval/>
        <timeout_days/>
        <field>
          <id>ID_BATCH</id>
          <enabled>Y</enabled>
          <name>ID_BATCH</name>
        </field>
        <field>
          <id>CHANNEL_ID</id>
          <enabled>Y</enabled>
          <name>CHANNEL_ID</name>
        </field>
        <field>
          <id>TRANSNAME</id>
          <enabled>Y</enabled>
          <name>TRANSNAME</name>
        </field>
        <field>
          <id>STATUS</id>
          <enabled>Y</enabled>
          <name>STATUS</name>
        </field>
        <field>
          <id>LINES_READ</id>
          <enabled>Y</enabled>
          <name>LINES_READ</name>
          <subject/>
        </field>
        <field>
          <id>LINES_WRITTEN</id>
          <enabled>Y</enabled>
          <name>LINES_WRITTEN</name>
          <subject/>
        </field>
        <field>
          <id>LINES_UPDATED</id>
          <enabled>Y</enabled>
          <name>LINES_UPDATED</name>
          <subject/>
        </field>
        <field>
          <id>LINES_INPUT</id>
          <enabled>Y</enabled>
          <name>LINES_INPUT</name>
          <subject/>
        </field>
        <field>
          <id>LINES_OUTPUT</id>
          <enabled>Y</enabled>
          <name>LINES_OUTPUT</name>
          <subject/>
        </field>
        <field>
          <id>LINES_REJECTED</id>
          <enabled>Y</enabled>
          <name>LINES_REJECTED</name>
          <subject/>
        </field>
        <field>
          <id>ERRORS</id>
          <enabled>Y</enabled>
          <name>ERRORS</name>
        </field>
        <field>
          <id>STARTDATE</id>
          <enabled>Y</enabled>
          <name>STARTDATE</name>
        </field>
        <field>
          <id>ENDDATE</id>
          <enabled>Y</enabled>
          <name>ENDDATE</name>
        </field>
        <field>
          <id>LOGDATE</id>
          <enabled>Y</enabled>
          <name>LOGDATE</name>
        </field>
        <field>
          <id>DEPDATE</id>
          <enabled>Y</enabled>
          <name>DEPDATE</name>
        </field>
        <field>
          <id>REPLAYDATE</id>
          <enabled>Y</enabled>
          <name>REPLAYDATE</name>
        </field>
        <field>
          <id>LOG_FIELD</id>
          <enabled>Y</enabled>
          <name>LOG_FIELD</name>
        </field>
        <field>
          <id>EXECUTING_SERVER</id>
          <enabled>N</enabled>
          <name>EXECUTING_SERVER</name>
        </field>
        <field>
          <id>EXECUTING_USER</id>
          <enabled>N</enabled>
          <name>EXECUTING_USER</name>
        </field>
        <field>
          <id>CLIENT</id>
          <enabled>N</enabled>
          <name>CLIENT</name>
        </field>
      </trans-log-table>
      <perf-log-table>
        <connection/>
        <schema/>
        <table/>
        <interval/>
        <timeout_days/>
        <field>
          <id>ID_BATCH</id>
          <enabled>Y</enabled>
          <name>ID_BATCH</name>
        </field>
        <field>
          <id>SEQ_NR</id>
          <enabled>Y</enabled>
          <name>SEQ_NR</name>
        </field>
        <field>
          <id>LOGDATE</id>
          <enabled>Y</enabled>
          <name>LOGDATE</name>
        </field>
        <field>
          <id>TRANSNAME</id>
          <enabled>Y</enabled>
          <name>TRANSNAME</name>
        </field>
        <field>
          <id>STEPNAME</id>
          <enabled>Y</enabled>
          <name>STEPNAME</name>
        </field>
        <field>
          <id>STEP_COPY</id>
          <enabled>Y</enabled>
          <name>STEP_COPY</name>
        </field>
        <field>
          <id>LINES_READ</id>
          <enabled>Y</enabled>
          <name>LINES_READ</name>
        </field>
        <field>
          <id>LINES_WRITTEN</id>
          <enabled>Y</enabled>
          <name>LINES_WRITTEN</name>
        </field>
        <field>
          <id>LINES_UPDATED</id>
          <enabled>Y</enabled>
          <name>LINES_UPDATED</name>
        </field>
        <field>
          <id>LINES_INPUT</id>
          <enabled>Y</enabled>
          <name>LINES_INPUT</name>
        </field>
        <field>
          <id>LINES_OUTPUT</id>
          <enabled>Y</enabled>
          <name>LINES_OUTPUT</name>
        </field>
        <field>
          <id>LINES_REJECTED</id>
          <enabled>Y</enabled>
          <name>LINES_REJECTED</name>
        </field>
        <field>
          <id>ERRORS</id>
          <enabled>Y</enabled>
          <name>ERRORS</name>
        </field>
        <field>
          <id>INPUT_BUFFER_ROWS</id>
          <enabled>Y</enabled>
          <name>INPUT_BUFFER_ROWS</name>
        </field>
        <field>
          <id>OUTPUT_BUFFER_ROWS</id>
          <enabled>Y</enabled>
          <name>OUTPUT_BUFFER_ROWS</name>
        </field>
      </perf-log-table>
      <channel-log-table>
        <connection/>
        <schema/>
        <table/>
        <timeout_days/>
        <field>
          <id>ID_BATCH</id>
          <enabled>Y</enabled>
          <name>ID_BATCH</name>
        </field>
        <field>
          <id>CHANNEL_ID</id>
          <enabled>Y</enabled>
          <name>CHANNEL_ID</name>
        </field>
        <field>
          <id>LOG_DATE</id>
          <enabled>Y</enabled>
          <name>LOG_DATE</name>
        </field>
        <field>
          <id>LOGGING_OBJECT_TYPE</id>
          <enabled>Y</enabled>
          <name>LOGGING_OBJECT_TYPE</name>
        </field>
        <field>
          <id>OBJECT_NAME</id>
          <enabled>Y</enabled>
          <name>OBJECT_NAME</name>
        </field>
        <field>
          <id>OBJECT_COPY</id>
          <enabled>Y</enabled>
          <name>OBJECT_COPY</name>
        </field>
        <field>
          <id>REPOSITORY_DIRECTORY</id>
          <enabled>Y</enabled>
          <name>REPOSITORY_DIRECTORY</name>
        </field>
        <field>
          <id>FILENAME</id>
          <enabled>Y</enabled>
          <name>FILENAME</name>
        </field>
        <field>
          <id>OBJECT_ID</id>
          <enabled>Y</enabled>
          <name>OBJECT_ID</name>
        </field>
        <field>
          <id>OBJECT_REVISION</id>
          <enabled>Y</enabled>
          <name>OBJECT_REVISION</name>
        </field>
        <field>
          <id>PARENT_CHANNEL_ID</id>
          <enabled>Y</enabled>
          <name>PARENT_CHANNEL_ID</name>
        </field>
        <field>
          <id>ROOT_CHANNEL_ID</id>
          <enabled>Y</enabled>
          <name>ROOT_CHANNEL_ID</name>
        </field>
      </channel-log-table>
      <step-log-table>
        <connection/>
        <schema/>
        <table/>
        <timeout_days/>
        <field>
          <id>ID_BATCH</id>
          <enabled>Y</enabled>
          <name>ID_BATCH</name>
        </field>
        <field>
          <id>CHANNEL_ID</id>
          <enabled>Y</enabled>
          <name>CHANNEL_ID</name>
        </field>
        <field>
          <id>LOG_DATE</id>
          <enabled>Y</enabled>
          <name>LOG_DATE</name>
        </field>
        <field>
          <id>TRANSNAME</id>
          <enabled>Y</enabled>
          <name>TRANSNAME</name>
        </field>
        <field>
          <id>STEPNAME</id>
          <enabled>Y</enabled>
          <name>STEPNAME</name>
        </field>
        <field>
          <id>STEP_COPY</id>
          <enabled>Y</enabled>
          <name>STEP_COPY</name>
        </field>
        <field>
          <id>LINES_READ</id>
          <enabled>Y</enabled>
          <name>LINES_READ</name>
        </field>
        <field>
          <id>LINES_WRITTEN</id>
          <enabled>Y</enabled>
          <name>LINES_WRITTEN</name>
        </field>
        <field>
          <id>LINES_UPDATED</id>
          <enabled>Y</enabled>
          <name>LINES_UPDATED</name>
        </field>
        <field>
          <id>LINES_INPUT</id>
          <enabled>Y</enabled>
          <name>LINES_INPUT</name>
        </field>
        <field>
          <id>LINES_OUTPUT</id>
          <enabled>Y</enabled>
          <name>LINES_OUTPUT</name>
        </field>
        <field>
          <id>LINES_REJECTED</id>
          <enabled>Y</enabled>
          <name>LINES_REJECTED</name>
        </field>
        <field>
          <id>ERRORS</id>
          <enabled>Y</enabled>
          <name>ERRORS</name>
        </field>
        <field>
          <id>LOG_FIELD</id>
          <enabled>N</enabled>
          <name>LOG_FIELD</name>
        </field>
      </step-log-table>
      <metrics-log-table>
        <connection/>
        <schema/>
        <table/>
        <timeout_days/>
        <field>
          <id>ID_BATCH</id>
          <enabled>Y</enabled>
          <name>ID_BATCH</name>
        </field>
        <field>
          <id>CHANNEL_ID</id>
          <enabled>Y</enabled>
          <name>CHANNEL_ID</name>
        </field>
        <field>
          <id>LOG_DATE</id>
          <enabled>Y</enabled>
          <name>LOG_DATE</name>
        </field>
        <field>
          <id>METRICS_DATE</id>
          <enabled>Y</enabled>
          <name>METRICS_DATE</name>
        </field>
        <field>
          <id>METRICS_CODE</id>
          <enabled>Y</enabled>
          <name>METRICS_CODE</name>
        </field>
        <field>
          <id>METRICS_DESCRIPTION</id>
          <enabled>Y</enabled>
          <name>METRICS_DESCRIPTION</name>
        </field>
        <field>
          <id>METRICS_SUBJECT</id>
          <enabled>Y</enabled>
          <name>METRICS_SUBJECT</name>
        </field>
        <field>
          <id>METRICS_TYPE</id>
          <enabled>Y</enabled>
          <name>METRICS_TYPE</name>
        </field>
        <field>
          <id>METRICS_VALUE</id>
          <enabled>Y</enabled>
          <name>METRICS_VALUE</name>
        </field>
      </metrics-log-table>
    </log>
    <maxdate>
      <connection/>
      <table/>
      <field/>
      <offset>0.0</offset>
      <maxdiff>0.0</maxdiff>
    </maxdate>
    <size_rowset>10000</size_rowset>
    <sleep_time_empty>50</sleep_time_empty>
    <sleep_time_full>50</sleep_time_full>
    <unique_connections>N</unique_connections>
    <feedback_shown>Y</feedback_shown>
    <feedback_size>50000</feedback_size>
    <using_thread_priorities>Y</using_thread_priorities>
    <shared_objects_file/>
    <capture_step_performance>N</capture_step_performance>
    <step_performance_capturing_delay>1000</step_performance_capturing_delay>
    <step_performance_capturing_size_limit>100</step_performance_capturing_size_limit>
    <dependencies>
    </dependencies>
    <partitionschemas>
    </partitionschemas>
    <slaveservers>
    </slaveservers>
    <clusterschemas>
    </clusterschemas>
    <created_user>-</created_user>
    <created_date>2026/03/18 13:56:41.476</created_date>
    <modified_user>-</modified_user>
    <modified_date>2026/03/18 13:56:41.476</modified_date>
    <key_for_session_key/>
    <is_key_private>N</is_key_private>
  </info>
  <notepads>
  </notepads>
  <order>
    <hop>
      <from>生成所需数据</from>
      <to>计算总页数</to>
      <enabled>Y</enabled>
    </hop>
    <hop>
      <from>计算总页数</from>
      <to>数据类型转换</to>
      <enabled>Y</enabled>
    </hop>
    <hop>
      <from>数据类型转换</from>
      <to>判断Pagesize是否为空</to>
      <enabled>Y</enabled>
    </hop>
    <hop>
      <from>判断Pagesize是否为空</from>
      <to>写日志</to>
      <enabled>Y</enabled>
    </hop>
    <hop>
      <from>判断Pagesize是否为空</from>
      <to>非空的走接口请求</to>
      <enabled>Y</enabled>
    </hop>
  </order>
  <step>
    <name>生成所需数据</name>
    <type>RowGenerator</type>
    <description/>
    <distribute>Y</distribute>
    <custom_distribution/>
    <copies>1</copies>
    <partitioning>
      <method>none</method>
      <schema_name/>
    </partitioning>
    <fields>
      <field>
        <name>total</name>
        <type>Number</type>
        <format/>
        <currency/>
        <decimal/>
        <group/>
        <nullif>100</nullif>
        <length>-1</length>
        <precision>-1</precision>
        <set_empty_string>N</set_empty_string>
      </field>
      <field>
        <name>pageSize</name>
        <type>Number</type>
        <format/>
        <currency/>
        <decimal/>
        <group/>
        <nullif/>
        <length>-1</length>
        <precision>-1</precision>
        <set_empty_string>N</set_empty_string>
      </field>
    </fields>
    <limit>1</limit>
    <never_ending>N</never_ending>
    <interval_in_ms>5000</interval_in_ms>
    <row_time_field>now</row_time_field>
    <last_time_field>FiveSecondsAgo</last_time_field>
    <attributes/>
    <cluster_schema/>
    <remotesteps>
      <input>
      </input>
      <output>
      </output>
    </remotesteps>
    <GUI>
      <xloc>112</xloc>
      <yloc>176</yloc>
      <draw>Y</draw>
    </GUI>
  </step>
  <step>
    <name>计算总页数</name>
    <type>ScriptValueMod</type>
    <description/>
    <distribute>Y</distribute>
    <custom_distribution/>
    <copies>1</copies>
    <partitioning>
      <method>none</method>
      <schema_name/>
    </partitioning>
    <compatible>N</compatible>
    <optimizationLevel>9</optimizationLevel>
    <jsScripts>
      <jsScript>
        <jsScript_type>0</jsScript_type>
        <jsScript_name>Script 1</jsScript_name>
        <jsScript_script>//Script here
var page_size = 10;
var total_count = total;
var totalPages = parseInt(total_count / page_size);
if (total_count % page_size > 0) totalPages++;

for (var i = 1; i &lt;= totalPages; i++) {
    // 输出每一页的页码
    putRow( [parseInt(i), page_size] ); 
}</jsScript_script>
      </jsScript>
    </jsScripts>
    <fields>    </fields>
    <attributes/>
    <cluster_schema/>
    <remotesteps>
      <input>
      </input>
      <output>
      </output>
    </remotesteps>
    <GUI>
      <xloc>304</xloc>
      <yloc>176</yloc>
      <draw>Y</draw>
    </GUI>
  </step>
  <step>
    <name>数据类型转换</name>
    <type>SelectValues</type>
    <description/>
    <distribute>Y</distribute>
    <custom_distribution/>
    <copies>1</copies>
    <partitioning>
      <method>none</method>
      <schema_name/>
    </partitioning>
    <fields>
      <select_unspecified>N</select_unspecified>
      <meta>
        <name>total</name>
        <rename>total</rename>
        <type>Integer</type>
        <length>-2</length>
        <precision>-2</precision>
        <conversion_mask/>
        <date_format_lenient>false</date_format_lenient>
        <date_format_locale/>
        <date_format_timezone/>
        <lenient_string_to_number>false</lenient_string_to_number>
        <encoding/>
        <decimal_symbol/>
        <grouping_symbol/>
        <currency_symbol/>
        <storage_type/>
      </meta>
      <meta>
        <name>pageSize</name>
        <rename>pageSize</rename>
        <type>Integer</type>
        <length>-2</length>
        <precision>-2</precision>
        <conversion_mask/>
        <date_format_lenient>false</date_format_lenient>
        <date_format_locale/>
        <date_format_timezone/>
        <lenient_string_to_number>false</lenient_string_to_number>
        <encoding/>
        <decimal_symbol/>
        <grouping_symbol/>
        <currency_symbol/>
        <storage_type/>
      </meta>
    </fields>
    <attributes/>
    <cluster_schema/>
    <remotesteps>
      <input>
      </input>
      <output>
      </output>
    </remotesteps>
    <GUI>
      <xloc>464</xloc>
      <yloc>144</yloc>
      <draw>Y</draw>
    </GUI>
  </step>
  <step>
    <name>判断Pagesize是否为空</name>
    <type>SwitchCase</type>
    <description/>
    <distribute>Y</distribute>
    <custom_distribution/>
    <copies>1</copies>
    <partitioning>
      <method>none</method>
      <schema_name/>
    </partitioning>
    <fieldname>pageSize</fieldname>
    <use_contains>N</use_contains>
    <case_value_type>Integer</case_value_type>
    <case_value_format/>
    <case_value_decimal/>
    <case_value_group/>
    <default_target_step>非空的走接口请求</default_target_step>
    <cases>
      <case>
        <value/>
        <target_step>写日志</target_step>
      </case>
    </cases>
    <attributes/>
    <cluster_schema/>
    <remotesteps>
      <input>
      </input>
      <output>
      </output>
    </remotesteps>
    <GUI>
      <xloc>640</xloc>
      <yloc>128</yloc>
      <draw>Y</draw>
    </GUI>
  </step>
  <step>
    <name>写日志</name>
    <type>WriteToLog</type>
    <description/>
    <distribute>Y</distribute>
    <custom_distribution/>
    <copies>1</copies>
    <partitioning>
      <method>none</method>
      <schema_name/>
    </partitioning>
    <loglevel>log_level_basic</loglevel>
    <displayHeader>Y</displayHeader>
    <limitRows>N</limitRows>
    <limitRowsNumber>0</limitRowsNumber>
    <logmessage/>
    <fields>
      </fields>
    <attributes/>
    <cluster_schema/>
    <remotesteps>
      <input>
      </input>
      <output>
      </output>
    </remotesteps>
    <GUI>
      <xloc>832</xloc>
      <yloc>128</yloc>
      <draw>Y</draw>
    </GUI>
  </step>
  <step>
    <name>非空的走接口请求</name>
    <type>HTTP</type>
    <description/>
    <distribute>Y</distribute>
    <custom_distribution/>
    <copies>1</copies>
    <partitioning>
      <method>none</method>
      <schema_name/>
    </partitioning>
    <url>http://192.168.0.3:8098/vmock/get/json</url>
    <urlInField>N</urlInField>
    <urlField/>
    <encoding>UTF-8</encoding>
    <httpLogin/>
    <httpPassword>Encrypted </httpPassword>
    <proxyHost/>
    <proxyPort/>
    <socketTimeout>10000</socketTimeout>
    <connectionTimeout>10000</connectionTimeout>
    <closeIdleConnectionsTime>-1</closeIdleConnectionsTime>
    <lookup>
      <arg>
        <name>total</name>
        <parameter>total</parameter>
      </arg>
      <arg>
        <name>pageSize</name>
        <parameter>pageSize</parameter>
      </arg>
    </lookup>
    <result>
      <name>result</name>
      <code/>
      <response_time/>
      <response_header/>
    </result>
    <attributes/>
    <cluster_schema/>
    <remotesteps>
      <input>
      </input>
      <output>
      </output>
    </remotesteps>
    <GUI>
      <xloc>832</xloc>
      <yloc>240</yloc>
      <draw>Y</draw>
    </GUI>
  </step>
  <step_error_handling>
  </step_error_handling>
  <slave-step-copy-partition-distribution>
  </slave-step-copy-partition-distribution>
  <slave_transformation>N</slave_transformation>
  <attributes/>
</transformation>
相关推荐
_饭团2 小时前
C语言数组全解析:从入门到精通
c语言·开发语言·数据结构·经验分享·笔记·学习·算法
踩着两条虫2 小时前
低代码 + AI,到底是生产力革命,还是下一代“技术债务”?
前端·人工智能·低代码
快乐柠檬不快乐2 小时前
C++中的代理模式实现
开发语言·c++·算法
良木生香2 小时前
【C++初阶】:C++类和对象(上):类的定义 & 类的实例化 & this指针
c语言·开发语言·c++
会编程的土豆2 小时前
【影院票务管理系统】
开发语言
南知意-2 小时前
cloud-app-admin:一款现代化、开箱即用的 Vue 3 后台管理模板
前端·javascript·vue.js·开源·开源项目
前端小王呀2 小时前
Vue 中高级开发面试题及答案
前端·javascript·vue.js
紫_龙2 小时前
最新版vue3+TypeScript开发入门到实战教程之watch与watchEffect对比区别
前端·vue.js·typescript
啪叽2 小时前
别再手写 if-else 选字体颜色了,CSS contrast-color() 来帮你处理
前端·css