Spring boot 整合kettle9.1 实现数据处理

  • 前言
  • 执行文件
  • 整体结构
  • 导入JAR包
  • POM文件配置
  • 导入kettle-password-encoder-plugins.xml文件
  • 执行方法
  • 参考对照
  • 断点查看执行结果
  • kettle-core版本源码对照
  • 源码解析
  • 文件变量结构
  • 执行结果
  • 执行结果对照
  • 总结


前言

记录项目需求的每日踩坑日记

执行文件

springboot 集成 JavaCV springboot 集成kettle_数据库


springboot 集成 JavaCV springboot 集成kettle_spring boot_02

整体结构

springboot 集成 JavaCV springboot 集成kettle_jar_03

导入JAR包

springboot 集成 JavaCV springboot 集成kettle_spring boot_04

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文件

springboot 集成 JavaCV springboot 集成kettle_spring boot_05

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;
    }

断点查看执行结果

代码执行还没修改变量时

springboot 集成 JavaCV springboot 集成kettle_运维_06


代码执行修改变量后,这里并没有修改到变量

springboot 集成 JavaCV springboot 集成kettle_java_07


修改的变量在properties中 所以设置变量模块中变量并没有任何变化

springboot 集成 JavaCV springboot 集成kettle_java_08

执行结果

springboot 集成 JavaCV springboot 集成kettle_数据库_09

kettle-core版本源码对照

springboot 集成 JavaCV springboot 集成kettle_spring boot_10


springboot 集成 JavaCV springboot 集成kettle_jar_11

这里可以看见9.1版本中没有 TwoWayPasswordEncoderInterface接口 ,如果没有这个接口程序就会报错,我暂时是两个包都引入了,目前还没发现什么问题。

源码解析

文件变量结构

springboot 集成 JavaCV springboot 集成kettle_jar_12

springboot 集成 JavaCV springboot 集成kettle_java_13

使用接口测试工具发送请求

//初始化程序
 	KettleEnvironment.init();
    JobMeta jm = new JobMeta(dirPath + File.separator + filename, null);

断点查看jm的结构

springboot 集成 JavaCV springboot 集成kettle_java_14


可以看见四个执行文件在jobcopies中,而需要修改的变量则是在entry下

springboot 集成 JavaCV springboot 集成kettle_运维_15

注意两个框中的数据类型

springboot 集成 JavaCV springboot 集成kettle_数据库_16


在JobEntryCopy中可以看见一个元素

springboot 集成 JavaCV springboot 集成kettle_spring boot_17


springboot 集成 JavaCV springboot 集成kettle_运维_18


在JobEntryInterface接口中是没有variableName、variableValue、variableType这三个元素只能在它 的实现类中去找

springboot 集成 JavaCV springboot 集成kettle_数据库_19


springboot 集成 JavaCV springboot 集成kettle_数据库_20


这里就找到了这三个元素,全部都是punlic 修饰 就说明不需要通过反射操作来获取这三个元素中的值,可以获取直接修改。

这个时候当代码执行到 start的时候 jm中的设置变量模块的entry中的variableName、variableValue两个元素的就已经被修改了

springboot 集成 JavaCV springboot 集成kettle_java_21

执行结果

springboot 集成 JavaCV springboot 集成kettle_数据库_22

执行结果对照

程序中修改变量后执行结果

springboot 集成 JavaCV springboot 集成kettle_java_23


Kettle中直接执行结果

springboot 集成 JavaCV springboot 集成kettle_运维_24

总结

踩坑,接着踩坑,不要停。