Spring boot 整合kettle9.1 实现数据处理
- 前言
- 执行文件
- 整体结构
- 导入JAR包
- POM文件配置
- 导入kettle-password-encoder-plugins.xml文件
- 执行方法
- 参考对照
- 断点查看执行结果
- kettle-core版本源码对照
- 源码解析
- 文件变量结构
- 执行结果
- 执行结果对照
- 总结
前言
记录项目需求的每日踩坑日记
执行文件
整体结构
导入JAR包
POM文件配置
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/jsch-0.1.55.jar</systemPath>
</dependency>
<dependency>
<groupId>org.pentaho.di</groupId>
<artifactId>kettle-core</artifactId>
<version>9.1.0.0-324</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/kettle-core-9.1.0.0-324.jar</systemPath>
</dependency>
<dependency>
<groupId>org.pentaho.di</groupId>
<artifactId>kettle-engine</artifactId>
<version>9.1.0.0-324</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/kettle-engine-9.1.0.0-324.jar</systemPath>
</dependency>
<dependency>
<groupId>org.pentaho.metastore</groupId>
<artifactId>metastore</artifactId>
<version>9.1.0.0-324</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/metastore-9.1.0.0-324.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-vfs2</artifactId>
<version>2.3</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/commons-vfs2-2.3.jar</systemPath>
</dependency>
<!-- https://mvnrepository.com/artifact/net.sourceforge.jtds/jtds -->
<dependency>
<groupId>net.sourceforge.jtds</groupId>
<artifactId>jtds</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/commons-logging-1.2.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/commons-io-2.2.jar</systemPath>
</dependency>
<!-- https://mvnrepository.com/artifact/commons-lang/commons-lang -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
//这里还需要导入连接数据库的驱动包
导入kettle-password-encoder-plugins.xml文件
kettle-password-encoder-plugins.xml文件在9.1版本中没有只能去8.2版本中去找放入resources目录下
执行方法
Controller编写
@GetMapping(value = "patientIn" )
public void patientIn() {
String fileName = "patientTrans.kjb";
HashMap<String, String> strMap = new HashMap<>();
strMap.put("starttime","2021-06-01");
strMap.put("namesfile","新建文件");
kettleService.runKjb(fileName, strMap);
}
这里只展示操作kjb文件的方法
/**
* 执行kjb文件
* @param filename 文件名
* @param params 传递的变量
* dirPath 文件路径
* @return
*/
public void runKjb(String filename, Map<String, String> params) {
System.out.println(filename+"文件开始执行!");
try {
KettleEnvironment.init();
JobMeta jm = new JobMeta(dirPath + File.separator + filename, null);
int j = -1;
List<JobEntryCopy> jobCopies = jm.getJobCopies();
for (JobEntryCopy jobCopy : jobCopies) {
if(jobCopy.equals("设置变量")){
j = jobCopies.indexOf(jobCopy);
}
}
JobEntryCopy jobEntry = jm.getJobEntry(j);
//存储信息
JobEntrySetVariables jobEntrySetVariables = (JobEntrySetVariables)jobEntry.getEntry();
jobEntrySetVariables.getPluginId();
jobEntrySetVariables.getVariableType();
if (params != null) {
//创建一个新的Entry
Iterator<Map.Entry<String, String>> entries = params.entrySet().iterator();
String[] arrName = new String[params.size()];
String[] arrValue = new String[params.size()];
int i = 0;
while (entries.hasNext()) {
Map.Entry<String, String> entry = entries.next();
arrName[i]=entry.getKey();
arrValue[i]=entry.getValue();
i++;
}
i = 0;
jobEntrySetVariables.variableName=arrName;
jobEntrySetVariables.variableValue=arrValue;
}
jobEntry.setEntry(jobEntrySetVariables);
jm.setJobEntry(1,jobEntry);
Job job = new Job(null, jm);
job.start();
job.waitUntilFinished();
System.out.println(filename+"文件执行完毕!");
} catch (Exception e) {
e.printStackTrace();
String er = e.getMessage();
System.out.println(filename+"文件执行异常!");
}
}
代码中的设置变量则是kjb文件中的一个执行模块
以上条件满足就可以执行代码了
参考对照
在借鉴其他博客的操作方法实践并不能直接修改到文件中需要的修改的变量
/**
* 执行kjb文件
* @param filename
* @param params
* @return
*/
public ResponseMsg<KettleResult> runKjb(String filename, Map<String, String> params) {
final ResponseMsg<KettleResult> response = new ResponseMsg<>();
try {
KettleEnvironment.init();
JobMeta jm = new JobMeta(dirPath + File.separator + filename, null);
Job job = new Job(null, jm);
if (params != null) {
Iterator<Map.Entry<String, String>> entries = params.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = entries.next();
job.setVariable(entry.getKey(), entry.getValue());
}
}
job.start();
job.waitUntilFinished();
response.setHead(ResponseHead.buildSuccessHead());
} catch (Exception e) {
e.printStackTrace();
String er = e.getMessage();
response.setHead(ResponseHead.buildFailedHead(er));
}
return response;
}
断点查看执行结果
代码执行还没修改变量时
代码执行修改变量后,这里并没有修改到变量
修改的变量在properties中 所以设置变量模块中变量并没有任何变化
执行结果
kettle-core版本源码对照
这里可以看见9.1版本中没有 TwoWayPasswordEncoderInterface接口 ,如果没有这个接口程序就会报错,我暂时是两个包都引入了,目前还没发现什么问题。
源码解析
文件变量结构
使用接口测试工具发送请求
//初始化程序
KettleEnvironment.init();
JobMeta jm = new JobMeta(dirPath + File.separator + filename, null);
断点查看jm的结构
可以看见四个执行文件在jobcopies中,而需要修改的变量则是在entry下
注意两个框中的数据类型
在JobEntryCopy中可以看见一个元素
在JobEntryInterface接口中是没有variableName、variableValue、variableType这三个元素只能在它 的实现类中去找
这里就找到了这三个元素,全部都是punlic 修饰 就说明不需要通过反射操作来获取这三个元素中的值,可以获取直接修改。
这个时候当代码执行到 start的时候 jm中的设置变量模块的entry中的variableName、variableValue两个元素的就已经被修改了
执行结果
执行结果对照
程序中修改变量后执行结果
Kettle中直接执行结果
总结
踩坑,接着踩坑,不要停。