当前位置 博文首页 > 盛夏温暖流年:Kettle7.0实现主键,索引迁移

    盛夏温暖流年:Kettle7.0实现主键,索引迁移

    作者:[db:作者] 时间:2021-07-13 21:41

    之前的博客提到过,kettle的数据抽取主要在于抽取数据,而没有考虑数据库的函数、存储过程、视图、表结构以及索引、约束等,但这些对于数据库来说又是至关重要的,所以我们需要通过修改源码的方式来实现。

    具体实现方式为:扩展kettle向导中的多表复制菜单里的功能,在该功能创建的作业中添加节点用于添加输出表的主键和索引。

    一、Kettle源码下载

    目前我使用的是kettle7.0.0版本,下载的源码版本要与之对应,git下载地址:

    https://github.com/pentaho/pentaho-kettle/tree/7.0.0.0-R

    在master下选择tags选项卡,选取自己需要的版本:
    这里写图片描述

    现在我们拥有了发行版kettle工具和对应的源码,就可以开始进行修改了。

    二、Kettle源码运行

    1.创建java项目

    新建java项目并在项目根目录下建立core,dbdialog,engine,ui,plugins,lib文件夹。
    这里写图片描述
    分别将源码目录下的代码拷贝到对应的项目文件下:

    这里写图片描述
    拷贝之后各个文件内容如下:
    Core,engine,ui,dialog文件内容:
    这里写图片描述
    plugins文件内容:
    这里写图片描述
    将发行版kettle工具免安装包的lib,libswt,launcher,simple-jndi 四个文件夹拷贝至java项目的根目录,全部拷贝完成后,当前项目根目录下有这些文件:
    这里写图片描述
    然后删除lib下的这3个jar包:
    这里写图片描述
    选择项目,右键——》Build Path——》Add Libraries——》next——》User Libraries——》New,新建一个library——》选中新建立的library,点击Add JARS——》选中项目下lib目录下的所有jar,以及根据自己电脑型号选择对应的libswt下的swt.jar,点击OK。
    比如我的电脑是64位的,就选择win64:
    这里写图片描述
    然后选择core、dbdialog、engine、ui四个目录,右键——》Build Path——》Use as Source Folder。
    这里写图片描述
    测试是否配置成功,需要找到ui/org/pentaho/di/ui/spoon/Spoon.java,右键运行即可,若出现程序界面,表示配置成功。

    三、Kettle源码修改

    找到项目目录下的ui/org/pentaho/di/ui/spoon/delegates/SpoonJobDelegate.java方法,这个就是我们主要需要修改的地方。

    首先要在这个类的包下面加个工具类用来实现对索引和约束的迁移,工具类代码的git地址如下:

    https://gist.github.com/javachen/1564353

    修改SpoonJobDelegate.java,在ripDB方法里面添加如下代码(在大约750行左右添加):

    Class.forName("com.mysql.jdbc.Driver");
    Class.forName("oracle.jdbc.driver.OracleDriver");
    String sourceMsg = sourceDbInfo.getHostname() + ":" + sourceDbInfo.getDatabasePortNumberString() + ":" + sourceDbInfo.getDatabaseName();
    String targetMsg = targetDbInfo.getHostname() + ":" + targetDbInfo.getDatabasePortNumberString() + "/" + targetDbInfo.getDatabaseName();
    Connection sourceCon = DriverManager.getConnection(
                        "jdbc:oracle:thin:@" + sourceMsg, sourceDbInfo.getUsername(), sourceDbInfo.getPassword());
    Connection targetCon = DriverManager.getConnection(
                        "jdbc:mysql://" + targetMsg, targetDbInfo.getUsername(), targetDbInfo.getPassword());
    
    String pksql = SpoonUtil.exportPkAndIndex(
                        sourceDbInfo, sourceCon, tables[i],
                        targetDbInfo, targetCon, tables[i]);
    if (!Const.isEmpty(pksql)) {
    location.x += 300;
        JobEntrySQL jesql = new JobEntrySQL(BaseMessages.getString(PKG,"Spoon.RipDB.AddPkAndIndex")
                            + tables[i] + "]");
        jesql.setDatabase(targetDbInfo);
        jesql.setSQL(pksql);
        jesql.setDescription(BaseMessages.getString(PKG,
        "Spoon.RipDB.AddPkAndIndex")
        + tables[i]
        + "]");
        JobEntryCopy jecsql = new JobEntryCopy();
        jecsql.setEntry(jesql);
    jecsql.setLocation(new Point(location.x, location.y));
        jecsql.setDrawn();
        jobMeta.addJobEntry(jecsql);
        // Add the hop too...
        JobHopMeta jhi = new JobHopMeta(previous, jecsql);
        jobMeta.addJobHop(jhi);
        previous = jecsql;
    }

    由于需求就是要把oracle数据库迁移到mysql,我的连接信息直接写死了,如果想灵活获取,也可以自行修改。

    修改完成后最好clean一下再运行程序,之前我没有clean,报了找不到文件之类的错误,排查了半天才发现clean一下就解决了······

    四、Kettle使用

    按照上一篇Kettle文档中的操作,新建Job后建立oracle和mysql的数据库连接,配置mysql的编码,之后选择源数据库和目标数据库,选择需要导入的表,最后输入对应的job名称和存储位置即可生成最新的job:
    这里写图片描述

    可以看出,相对于修改之前Job,修改源码之后多出了中间添加主键和索引约束步骤,执行当前Job,就可以将oracle中的主键和索引迁移到mysql了。

    本博客参考了以下博客,里面还提到了插件相关的操作:
    http://www.zuidaima.com/blog/3670924901010432.htm

    cs