Springboot整合ETL引擎Kettle的使用

简介

ETL是英文Extract-Transform-Load的缩写,用来描述将数据从源端经过抽取(extract)、转换(transform)、加载(load)至目的端的过程,它能够对各种分布的、异构的源数据(如关系数据)进行抽取,按照预先设计的规则将不完整数据、重复数据以及错误数据等“脏"数据内容进行清洗,得到符合要求的“干净”数据,并加载到数据仓库中进行存储,这些“干净”数据就成为了数据分析、数据挖掘的基石。

kettle是一个开源ETL工具。kettle提供了基于java的图形化界面,使用很方便。kettle提供了基于 JAVA的脚步编写功能,可以灵活地自定义ETL过程,使自行定制、批量处理等成为可能,这才是一个程序员需要做的工作,而不仅是象使用word一样操作 kettle用户界面。

环境集成:

参考:java集成kettle教程(附示例代码)_kettle java_成伟平2022的博客-CSDN博客

代码:

pom.xml添加:

<!--mysql数据库链接驱动以及连接池-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.11</version>
        </dependency>
<!-- kettle 工具本地jar包加载 -->
        <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>kettle-core</artifactId>
            <version>8.2.0.7-719</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/kettle-core-8.2.0.7-719.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>kettle-engine</artifactId>
            <version>8.2.0.7-719</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/kettle-engine-8.2.0.7-719.jar</systemPath>
        </dependency>
        <dependency>
            <groupId>pentaho-kettle</groupId>
            <artifactId>metastore</artifactId>
            <version>8.2.0.7-719</version>
            <scope>system</scope>
            <systemPath>${project.basedir}/lib/metastore-8.2.0.7-719.jar</systemPath>
        </dependency>
        <!--kettle需要用到的其它依赖-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-vfs2</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>17.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.2</version>
        </dependency>
        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.6</version>
        </dependency>
        <dependency>
            <groupId>commons-codec</groupId>
            <artifactId>commons-codec</artifactId>
            <version>1.10</version>
        </dependency>
        <dependency>
            <groupId>com.jcraft</groupId>
            <artifactId>jsch</artifactId>
            <version>0.1.54</version>
        </dependency>
        <dependency>
            <groupId>net.sourceforge.jexcelapi</groupId>
            <artifactId>jxl</artifactId>
            <version>2.6.12</version>
        </dependency>
@RestController
@RequestMapping("${application.admin-path}/etl-kettl")
//@Api(tags = "ETL-Kettle的demo接口")
public class KettleDemoContrllor {
	@Resource
	KettleService kettleService;

	@GetMapping("/execKtr")
	//@ApiOperation("执行ktr文件")
	private Object runKtr(String filename) throws Exception {
		return R.buildOkData(kettleService.runTaskKtr(filename,null).toString());
	}

	@GetMapping("/execKjb")
	//@ApiOperation("执行kjb文件")
	private Object runKjb(String filename) throws Exception {
		return R.buildOkData(kettleService.runTaskKjb(filename, null).toString());
	}
}

public interface KettleService {
    /**
     * 开始执行ETL任务(ktr文件)
     *
     * @param taskFileName 执行的任务文件名(ktr)
     * @param params 执行任务输入的参数
     * @return 运行结果
     * @throws Exception 没有找到配置文件,Kettle的运行异常不会抛出
     */
    Object runTaskKtr(String taskFileName, Map<String, String> params) throws Exception;
    /**
     * 开始执行ETL任务(kjb文件)
     *
     * @param taskFileName 执行的任务文件名(kjb)
     * @param params 执行任务输入的参数
     * @return 运行结果
     * @throws Exception 没有找到配置文件,Kettle的运行异常不会抛出
     */
    Object runTaskKjb(String taskFileName, Map<String, String> params) throws Exception;
}
@Service
public class KettleServiceImpl implements KettleService {

    @Value("${kettle.script.path}")
    private String kettleScriptPath;

    private static final Logger logger = LoggerFactory.getLogger("kettle-service-log");

    private final List<KtrMeta> KTR_METAS = new ArrayList<>();
    private final List<KjbMeta> KJB_METAS = new ArrayList<>();

    private List<String> getFiles(String path, String subName) {
        List<String> files = new ArrayList<>();
        File file = new File(path);
        File[] tempList = file.listFiles();
        if (tempList == null){
            return files;
        }
        for (File value : tempList) {
            if (value.isFile()) {
                if (Objects.equals(value.toString().substring(value.toString().length() - 3), subName)) {
                    files.add(value.getName());
                }
            }
        }
        return files;
    }

    //采用单列模式,项目启动时加载环境,加载所有的转换配置、任务配置,后续执行就会快一点
    //@PostConstruct
    public void init() throws KettleException {
        logger.info("----------------------开始初始化ETL配置------------------------");
        KettleEnvironment.init();
        List<String> ktrFiles = getFiles(kettleScriptPath, "ktr");
        List<String> kjbFiles = getFiles(kettleScriptPath, "kjb");
        logger.info("需要加载的转换为:" + ktrFiles.toString());
        logger.info("需要加载的任务为:" + kjbFiles.toString());
        logger.info("----------------------开始加载ETL配置--------------------------");
        for (String ktrFile : ktrFiles) {
            KtrMeta ktrMeta = new KtrMeta();
            ktrMeta.setName(ktrFile);
            ktrMeta.setTransMeta(new TransMeta(kettleScriptPath + ktrFile));
            KTR_METAS.add(ktrMeta);
            logger.info("成功加载转换配置:" + ktrFile);
        }
        for (String kjbFile : kjbFiles) {
            KjbMeta kjbMeta = new KjbMeta();
            kjbMeta.setName(kjbFile);
            kjbMeta.setJobMeta(new JobMeta(kettleScriptPath + kjbFile, null));
            KJB_METAS.add(kjbMeta);
            logger.info("成功加载任务配置:" + kjbFile);
        }
        logger.info("----------------------全部ETL配置加载完毕-----------------------");
    }


    @Override
    public Object runTaskKtr(String ktrFileName, Map<String, String> params) {
        logger.info("开始执行转换:" + ktrFileName);
        TransMeta transMeta = null;
        for (KtrMeta ktrMeta : KTR_METAS) {
            if(Objects.equals(ktrFileName,ktrMeta.getName())){
                transMeta = ktrMeta.getTransMeta();
                break;
            }
        }
        //如果在缓存的列表里面没找到需要自信的配置,尝试手动加载
        try {
            if (transMeta == null) {
                logger.warn("资源池没有找到配置文件:" + ktrFileName+"  尝试二次加载!");
                KettleEnvironment.init();
                transMeta = new TransMeta(kettleScriptPath + File.separator + ktrFileName);
                if(transMeta==null) throw new RuntimeException("未找到需要执行的转换配置文件:");
            }
            Trans trans = new Trans(transMeta);
            if (params != null) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    trans.setParameterValue(entry.getKey(), entry.getValue());
                }
            }
            //trans.prepareExecution(null);
            //trans.startThreads(); //启用新的线程加载
            trans.execute(null);
            trans.waitUntilFinished();
            return trans.getResult();
        }catch (Exception e)
        {
            e.printStackTrace();
            return e.getMessage();
        }

    }

    @Override
    public Object runTaskKjb(String objFileName, Map<String, String> params) throws Exception {
        logger.info("开始执行任务:" + objFileName);
        JobMeta jobMeta = null;
        for (KjbMeta kjbMeta : KJB_METAS) {
            if(Objects.equals(objFileName,kjbMeta.getName())){
                jobMeta = kjbMeta.getJobMeta();
            }
        }
        try {
            if (jobMeta == null) {
                logger.warn("资源池没有找到配置文件:" + objFileName+"  尝试二次加载!");
                KettleEnvironment.init();
                jobMeta = new JobMeta(kettleScriptPath + File.separator + objFileName,null);
                if(jobMeta==null) throw new RuntimeException("未找到需要执行的任务配置文件:"+objFileName);
            }
            Job job = new Job(null, jobMeta);
            if (params != null) {
                for (Map.Entry<String, String> entry : params.entrySet()) {
                    job.setParameterValue(entry.getKey(), entry.getValue());
                }
            }
            job.start();
            job.waitUntilFinished();
            return job.getResult();
        }catch (Exception e)
        {
            e.printStackTrace();
            return e.getMessage();
        }

    }
}
@Data
public class KtrMeta {
	private TransMeta transMeta;
	private String name;
}
@Data
public class KjbMeta {
	private JobMeta jobMeta;
	private String name;
}

总结:

集成后感觉没什么必要集成到项目里面去。关键还是需要学会工具的使用,以便进行数据收集与治理。

参考:1_ETL和Kettle概述_哔哩哔哩_bilibili

下载: kettle工具下载

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
### 回答1: Spring Boot是一个快速开发框架,而Kettle是一个强大的ETL工具。将它们整合在一起可以实现数据的快速导入和导出。 首先,需要在pom.xml文件中添加Kettle的依赖: ``` <dependency> <groupId>org.pentaho</groupId> <artifactId>kettle-core</artifactId> <version>8.3..-371</version> </dependency> ``` 然后,在Spring Boot的配置文件中添加Kettle的配置: ``` kettle: home: /opt/kettle repository: /opt/kettle/repo ``` 其中,kettle.home是Kettle的安装目录,kettle.repository是Kettle的资源库目录。 接下来,可以在Spring Boot的代码中使用Kettle的API来实现数据的导入和导出。例如: ``` @Autowired private KettleEnvironment kettleEnvironment; public void importData() throws KettleException { kettleEnvironment.init(); KettleEnvironment.setExecutionConfiguration(null); TransMeta transMeta = new TransMeta("/opt/kettle/trans/import.ktr"); Trans trans = new Trans(transMeta); trans.execute(null); trans.waitUntilFinished(); } public void exportData() throws KettleException { kettleEnvironment.init(); KettleEnvironment.setExecutionConfiguration(null); JobMeta jobMeta = new JobMeta("/opt/kettle/job/export.kjb", null); Job job = new Job(null, jobMeta); job.start(); job.waitUntilFinished(); } ``` 以上代码分别实现了数据的导入和导出,其中import.ktr和export.kjb是Kettle的转换和作业文件。 最后,需要注意的是,Kettle的API在使用时需要先初始化Kettle环境,否则会报错。因此,在Spring Boot的启动类中需要添加以下代码: ``` @SpringBootApplication public class Application implements CommandLineRunner { @Autowired private KettleEnvironment kettleEnvironment; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Override public void run(String... args) throws Exception { kettleEnvironment.init(); } } ``` 这样,就完成了Spring Boot整合Kettle的配置和使用。 ### 回答2: Kettle是一个ETL(Extract, Transform, Load)工具,也是PDI(Pentaho Data Integration)的核心组件之一。Spring Boot是一个流行的开发框架,它可以大大简化应用程序的开发过程。Spring Boot和Kettle是两个不同的工具,但是它们可以很好地整合在一起,让开发人员更容易地实现数据处理任务。 下面是Spring Boot整合Kettle的几个关键步骤: 1. 导入Kettle依赖 在Spring Boot项目的pom.xml文件中,添加Kettle的依赖。可以在Maven中央仓库中找到这些依赖项,例如: ``` <dependency> <groupId>org.pentaho</groupId> <artifactId>kettle-core</artifactId> <version>9.1.0.0-324</version> </dependency> <dependency> <groupId>org.pentaho</groupId> <artifactId>kettle-ui-swt</artifactId> <version>9.1.0.0-324</version> </dependency> ``` 2. 配置Kettle 在Spring Boot项目的配置文件中,添加Kettle的相关配置。例如,可以设置Kettle的安装路径、数据库连接信息等。以下是一个示例配置: ``` kettle.home=C:/kettle kettle.db.driver=org.postgresql.Driver kettle.db.url=jdbc:postgresql://localhost/test kettle.db.user=postgres kettle.db.pass=password kettle.db.schema=public ``` 3. 编写Kettle任务 在Spring Boot项目中,可以编写Kettle任务。可以使用Kettle自带的设计器(Spoon)创建任务,也可以使用代码编写任务。以下是一个示例任务: ``` <transformation> <info> <name>example_transform</name> </info> <step> <name>input</name> <type>TextFileInput</type> <description>Read input text file</description> <filename>input.txt</filename> <delimiter>,</delimiter> <enclosure>"</enclosure> <header>Y</header> <lazy_conversion>Y</lazy_conversion> <dateFormatLenient>Y</dateFormatLenient> <dateFormatLocale></dateFormatLocale> </step> <step> <name>cleanse</name> <type>FilterRows</type> <description>Cleanse invalid data</description> <condition>NOT( [field1] IS NULL OR [field2] IS NULL )</condition> </step> <step> <name>output</name> <type>TextFileOutput</type> <description>Write output text file</description> <filename>output.txt</filename> <delimiter>,</delimiter> <enclosure>"</enclosure> <header>Y</header> <splitEvery>-1</splitEvery> </step> <hop> <from>input</from> <to>cleanse</to> </hop> <hop> <from>cleanse</from> <to>output</to> </hop> </transformation> ``` 4. 执行Kettle任务 在Spring Boot项目中,可以使用Kettle的Java API执行任务。以下是一个示例代码: ``` @Configuration public class KettleConfig { @Autowired private Environment env; @Bean public KettleEnvironment kettleEnvironment() throws KettleException { KettleEnvironment.init(); return KettleEnvironment.getInstance(); } @Bean public DatabaseMeta databaseMeta() { String driver = env.getProperty("kettle.db.driver"); String url = env.getProperty("kettle.db.url"); String user = env.getProperty("kettle.db.user"); String pass = env.getProperty("kettle.db.pass"); String schema = env.getProperty("kettle.db.schema"); DatabaseMeta dbMeta = new DatabaseMeta(); dbMeta.setDatabaseType("PostgreSQL"); dbMeta.setAccessType(DatabaseMeta.TYPE_ACCESS_JNDI); dbMeta.setName("test"); dbMeta.addExtraOption("INITIAL_POOL_SIZE", "10"); dbMeta.addExtraOption("MAXIMUM_POOL_SIZE", "100"); dbMeta.setJdbcDriver(driver); dbMeta.setDBName(url); dbMeta.setUsername(user); dbMeta.setPassword(pass); dbMeta.setPreferredSchemaName(schema); return dbMeta; } @Bean public Trans trans(DatabaseMeta databaseMeta) throws KettleException { KettleEnvironment.init(); TransMeta transMeta = new TransMeta("example_transform.ktr"); transMeta.setUsingUniqueConnections(true); transMeta.setMetaStore(KettleUtil.getMetaStore()); Trans trans = new Trans(transMeta); trans.setLogLevel(LogLevel.BASIC); trans.setMetaStore(KettleUtil.getMetaStore()); trans.setDatabaseMeta(databaseMeta); return trans; } } ``` 5. 监控任务执行 在Spring Boot项目中,可以编写代码来监控Kettle任务的执行情况,并生成相应的日志。可以使用Kettle的日志功能来记录任务执行过程中的错误和警告信息。以下是一个示例代码: ``` @Autowired private Trans trans; public void execute() throws KettleException { trans.execute(null); Result result = trans.getResult(); String status = result != null && result.getNrErrors() == 0 ? "SUCCESS" : "FAILED"; log.info("Kettle job execution {}.", status); if (result != null && result.getNrErrors() > 0) { for (LogMessage message : result.getLogChannel().getLogBuffer() ) { if (message.isError()) { log.error(message.getMessage()); } else if ( message.isWarning() ) { log.warn( message.getMessage() ); } else { log.info( message.getMessage() ); } } } } ``` 总之,Spring Boot和Kettle整合可以极大地简化数据处理任务的开发流程。通过采用KettleETL工具和Spring Boot的开发框架,开发人员可以更加高效地处理数据。同时,Kettle的强大功能也可以为Spring Boot项目提供更加丰富和灵活的数据处理能力。 ### 回答3: 随着数据量的不断增长,数据处理变得越来越重要,kettle是一款著名的数据处理工具,可以用于数据清洗、转换、集成等多种操作。而SpringBoot作为一款开发框架,充分发挥其快速开发的优势,简化了应用程序的配置和部署过程,也受到了众多Java开发者的追捧。因此,SpringBoot整合Kettle就成为了一种趋势。 SpringBootKettle整合的优点: (1)Kettle具有独立的编写、组装和执行ETL任务的能力,在大数据处理和企业数据仓库建设中使用广泛。这使得Kettle对于大规模数据处理来说是必不可少的。而SpringBoot作为一款快速开发的框架,能够简化开发流程,提高开发效率。 (2)Kettle支持的数据源和目标可以是各种数据库、CSV、XML等等,SpringBoot能够方便的处理数据源,和Kettle完美结合,可以轻松地完成ETL工作流的设计、发布和操作,从而实现数据的整合、转换和清洗。 (3)SpringBoot整合Kettle过程中,可以使用Spring Security,对于Kettle执行作业等操作进行权限访问控制,有效地保护数据安全。 SpringBoot整合Kettle的具体实现: (1)首先,需要在Maven中添加SpringBootKettle的相关依赖: <dependency> <groupId>org.pentaho</groupId> <artifactId>kettle-core</artifactId> <version>9.1.0.0-324</version> </dependency> <dependency> <groupId>org.pentaho</groupId> <artifactId>kettle-engine</artifactId> <version>9.1.0.0-324</version> </dependency> (2)其次,可以使用Kettle自带的Job和Transformation的API,通过编写Java代码实现Kettle的操作、执行等功能。 (3)如果要实现数据源的多样化,可以使用Spring Data,通过配置数据源的方式,实现与不同数据库的数据交互。 (4)为了防止数据的泄露,可以使用Spring Security来保护Kettle的资源,并控制用户权限。 总之,通过SpringBoot整合Kettle,能够实现快速开发、方便部署、易于维护等优点,实现数据清洗、转换、整合等多种操作,满足企业业务需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

萤火1129

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值