Java 调用 kettle,难的不是怎么调用,而是解决 maven 依赖冲突问题,
直接将 kettle 依赖,添加到我们的 maven 工程,可能会导致代码大范围报错;
解决方案也很简单,就是直接从 spoon 的 lib 目录下,复制我们所需的 jar 包,按需导入我们的工程。

主要用到的jar包如下,这些足以调起 kettle 脚本,剩下的还有 ftp、http 等服务,用啥加啥。

比如:下面没有 ftp 的依赖,如果 kettle 脚本是处理 ftp 的,那就会报错,
这时候就要根据报错信息,去 kettle 工程的pom.xml文件中,把 ftp 相关的依赖找出来。(去lib目录找jar包也一样)

这里就不提供工具包了,换成 apache 的 commons,照着意思自己改一改。

import cn.seaboot.commons.core.Converter;
import cn.seaboot.commons.exception.SystemError;
import cn.seaboot.commons.file.FileUtils;
import cn.seaboot.commons.file.IOUtils;
import cn.seaboot.commons.file.PropertiesUtils;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.core.logging.ChannelLogTable;
import org.pentaho.di.core.logging.JobEntryLogTable;
import org.pentaho.di.core.logging.JobLogTable;
import org.pentaho.di.job.Job;
import org.pentaho.di.job.JobMeta;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties; /**
* Kettle桥接器,通过这个类,调用使用Kettle提供的jar包运行脚本
* <p>
* KettleBridge kettleBridge = new KettleBridge();
* kettleBridge.init();
* kettleBridge.execute(filepath, null);
*
* @author Mr.css
* @version 2022-03-28 14:44
*/
@Service
public class KettleBridge {
private Logger logger = LoggerFactory.getLogger(KettleBridge.class); /**
* Kettle 环境初始化
*/
@PostConstruct
public void init() {
try {
KettleEnvironment.init();
logger.debug("【Configuration】Kettle environment init succeed!");
} catch (KettleException e) {
throw new SystemError("【Configuration】Kettle Environment build failed!", e);
}
} /**
* 设置输出日志,将日志输出到数据库表里
*
* @param jobMeta -
*/
private void initDatabase(JobMeta jobMeta) {
DatabaseMeta databaseMeta = new DatabaseMeta();
databaseMeta.setName("med");
databaseMeta.setDatabaseType("MySQL");
databaseMeta.setAccessType(DatabaseMeta.TYPE_ACCESS_NATIVE);
databaseMeta.setHostname("localhost");
databaseMeta.setDBName("med");
databaseMeta.setDBPort("3306");
databaseMeta.setUsername("root");
databaseMeta.setPassword("root");
jobMeta.addDatabase(databaseMeta); // databaseMeta.name 对应于下面的 connectionName // 任务日志
JobLogTable jobLogTable = JobLogTable.getDefault(jobMeta, jobMeta);
jobLogTable.setConnectionName("med");
jobLogTable.setSchemaName("med");
jobLogTable.setTableName("t_kettle_job_log");
jobMeta.setJobLogTable(jobLogTable); // 任务节点日志
JobEntryLogTable jobEntryLogTable = JobEntryLogTable.getDefault(jobMeta, jobMeta);
jobEntryLogTable.setConnectionName("med");
jobEntryLogTable.setSchemaName("med");
jobEntryLogTable.setTableName("t_kettle_item_log");
jobMeta.setJobEntryLogTable(jobEntryLogTable); // 任通道日志
ChannelLogTable channelLogTable = ChannelLogTable.getDefault(jobMeta, jobMeta);
channelLogTable.setConnectionName("med");
channelLogTable.setSchemaName("med");
channelLogTable.setTableName("t_kettle_channel_log");
jobMeta.setChannelLogTable(channelLogTable);
} /**
* Kettle 环境销毁
*/
@PreDestroy
public void shutdown() {
KettleEnvironment.shutdown();
} /**
* 执行kettle脚本,Kettle以文件作为脚本的最小单位,提供脚本所在的绝对路即可
*
* @param path 脚本路径
* @param params 脚本运行所需的参数变量
* @return 执行结果
* @throws KettleException run kettle cause any exception
* @throws IOException can not read kettle.properties
*/
public JobResult execute(String path, Map<String, Object> params) throws KettleException, IOException {
// 初始化job路径
JobMeta jobMeta = new JobMeta(path, null);
Job job = new Job(null, jobMeta); // 设置环境变量
Map<String, String> en = this.loadVariable(params);
for (Map.Entry<String, String> entry : en.entrySet()) {
job.setVariable(entry.getKey(), entry.getValue());
} // 日志设置
this.initDatabase(jobMeta); // 启动等待直到结束
job.start();
job.waitUntilFinished(); // 为了避免出现意外的编程,通过对象打包执行结果,不返回Job对象
JobResult result = new JobResult();
result.setBatchId(job.getBatchId());
result.setErrors(job.getErrors());
result.setPassedBatchId(job.getPassedBatchId());
result.setStatus(job.getStatus());
result.setParams(en);
return result;
} /**
* 载入环境变量
* 这种写法不是最优的,会损耗一部分性能,主要为了方便整理代码
*
* @param params 用户指定的变量
* @return 最终使用的变量
* @throws IOException 读取配置异常
*/
private Map<String, String> loadVariable(Map<String, Object> params) throws IOException {
Map<String, String> result = new HashMap<>(); // 用户文件夹下的kettle.properties
Properties properties = this.readKettleProperties();
if (properties != null) {
for (Map.Entry<Object, Object> entry : properties.entrySet()) {
result.put(Converter.toString(entry.getKey()), Converter.toString(entry.getValue()));
}
} // 用户指定的环境变量
if (params != null) {
for (Map.Entry<String, Object> entry : params.entrySet()) {
result.put(entry.getKey(), Converter.toString(entry.getValue()));
}
}
return result;
} /**
* 获取kettle配置参数,读取用户文件夹下的kettle.properties
*
* @return 参数
* @throws IOException can not read kettle.properties
*/
private Properties readKettleProperties() throws IOException {
String home = FileUtils.getUserDirectoryPath();
if (home != null) {
File file = new File(home, ".kettle/kettle.properties");
if (file.exists()) {
try (InputStream is = IOUtils.openFileInputStream(file)) {
return PropertiesUtils.load(is);
}
}
} else {
logger.debug("Can not found user.home, had batter find out why!");
}
return null;
}
}

Java调用Kettle的更多相关文章

  1. java调用kettle的job和transfer工具类

    package com.woaiyitiaocai.util; import java.util.Map; import java.util.UUID; import org.apache.log4j ...

  2. 运用Java调用Kettle Job和Trans(带参数)

    1.首先创建一个kettle trans 2.对表输入进行编辑 ${dateNow}为要传入的参数. 3.代码编写 首先需要把包导入 import org.pentaho.di.core.Kettle ...

  3. java程序调用kettle

    (1).将相应的kettle的jar包导入的java项目,主要的jar包有一下几个. (2).java程序. package cn.com.taiji.oosweb.test.web; import ...

  4. java调用kettle_实现(2)

    (1).参照“java调用kettle_导入jar包(1)”,应用etl工具下lib里的所有jar (2). 最近要对一个系统的数据同步到另一个系统中,要求新系统的数据结果完成之后,实时同步到另一个系 ...

  5. java调用kettle_导入jar包(1)

    版权声明:本文为博主原创文章,未经博主允许不得转载. Java调用Kettle执行任务或转换,需要使用Kettle中的jar,可以先导入lib目录中的几个基本的jar,如:kettle-core.ja ...

  6. 【Kettle】Java借助Kettle将Excel导入数据

    示例功能(仅供测试): 在JAVA项目中,将数据从Excel文件导入数据库中.实现该能有多种方法,而本例则是“不走寻常路”,尝试借助Kettle实现数据导入. 原理: Java中调用存储在Kettle ...

  7. java中调用kettle转换文件

    java中调用kettle转换文件 通过命令行也能够调用,然后java中调用命令行代码也能够.这样没有和java代码逻辑无缝集成.本文说明kettle5.1中假设通过其它API和java代码无缝集成: ...

  8. JAVA调用 keytool 生成keystore 和 cer 证书

    keytool是一个Java数据证书的管理工具, keytool将密钥(key)和证书(certificates)存在一个称为keystore的文件中在keystore里, 包含两种数据: 密钥实体( ...

  9. java调用mysql服务做备份与恢复

    首先添加mysql的bin到环境变量,这样可以简写部分命令,并且做到不依赖系统mysql的具体安装路径. 重启计算机可以让添加的环境变量在java代码中调用时生效.(cmd中生效但java中调用没有生 ...

  10. 存储过程详解与java调用(转)

    存储过程的一些基本语法: --------------创建存储过程----------------- CREATE PROC [ EDURE ] procedure_name [ ; number ] ...

随机推荐

  1. Word 设置页眉、页脚、页码

    页眉:在 Word 文档中,每个页面的顶部区域为页眉.常用于显示文档的附加信息,可以插入时间.图形.公司微标.文档标题.文件名或作者姓名等. 页脚:页脚与页眉的作用相同,都可以作为显示文档的附加信息, ...

  2. Integer使用==比较的问题

    Integer使用==比较的问题 new一个对象 public Integer(int value) { this.value = value; } 自动装箱 public static Intege ...

  3. 简单介绍Python中如何给字典设置默认值

    这篇文章主要介绍了Python中如何给字典设置默认值问题,具有很好的参考价值,希望对大家有所帮助.如有错误或未考虑完全的地方,望不吝赐教 Python字典设置默认值 我们都知道,在 Python 的字 ...

  4. Linus对Linux 6.3内核的合并解释不满

    Linux 6.3 内核的合并窗口已开启,Linus Torvalds 也收到了大量的 PR,目前总体看来正在有序进行.但 Linus 对部分合并请求的日志信息非常不满:"我之前就已经说过, ...

  5. python如何画高光谱立体图像

    语句含义:spectral.view_cube(image,bands=[29,19,9])  中的29,19和9是第几个波段,可以改成数据波段数以内的其他的数值

  6. CF1137F Matches Are Not a Child's Play 题解

    以最后被删去的点为根,这样子不会存在从父亲然后删掉某个点,儿子的删除顺序一定比父亲前. 记每个点子树中的最大值为 \(f_x\),那么一个点的排名,首先就需要加上 \(<f_x\) 的所有值,记 ...

  7. vue3中对于/deep/和::v-deep的警告信息处理

    目前发现两处警告信息: ::v-deep usage as a combinator has been deprecated. Use :deep() instead. the >>> ...

  8. 记录一次Python环境安装出现的问题(已安装java)

    之前是在其他电脑上安装python环境,没有问题. 换了一台电脑开始安装(注:已配置java环境) 安装包准备好 ( 这里使用的是python 3.6.5(64位) ,下载地址选择官网) 教程百度都有 ...

  9. 深入理解JVM - 自动内存管理

    对于从事C.C++程序开发的开发人员来说,在内存管理领域,他们既是拥有最高权力的"皇帝",又是从事最基础工作的劳动人民--既拥有每一个对象的"所有权",又担负着 ...

  10. python怎么实现正确的浮点数四舍五入

    round 以下示例展示对于结构相同的两组数据(1.03575000和1.03425000)保留小数后4位,使用内置函数round方法的输出结果,并不是需要的结果 print(round(1.0357 ...