设计目标:
把MySql的fromdb数据库的from_user表中数据拷贝到todb数据库的to_user表中;
预置条件:
首先在MySql中:
1.建立数据库fromdb,并创建from_user表
2.建立数据库todb,并创建to_user表
代码讲解:
1.1创建一个名字叫cgmTransName的转换
1.2在cgmTransName转换下的DB连接中创建2个数据库连接,分别叫fromDbName和toDbName
那么1.1+1.2对应的java代码为
2.创建步骤1:(输入:表输入)
对应的java代码为
3.创建步骤2:(输出:插入/更新)
对应的java代码为
4.创建节点连接
对应的java代码为
5.运行转换
对应的java代码为
运行成功之后
完整的代码结构如下:
pom.xml
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
www.test.com
test
0.0.1-SNAPSHOT
pentaho-kettle
kettle-core
7.1.0.0-12
pentaho-kettle
kettle-dbdialog
7.1.0.0-12
pentaho-kettle
kettle-engine
7.1.0.0-12
pentaho
metastore
7.1.0.0-12
org.apache.commons
commons-vfs2
2.2
com.google.guava
guava
19.0
mysql
mysql-connector-java
5.1.46
commons-lang
commons-lang
2.6
pentaho-releases
Kettle
https://nexus.pentaho.org/content/groups/omni/
public
aliyun nexus
http://maven.aliyun.com/nexus/content/groups/public/
true
KettleTest.java
package test;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransHopMeta;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.steps.insertupdate.InsertUpdateMeta;
import org.pentaho.di.trans.steps.tableinput.TableInputMeta;/**
* @author cgm
* @date 2019年7月8日
*/
public class KettleTest {
public static void main(String[] args) throws Exception {
KettleEnvironment.init();TransMeta transMeta = generateTrans();
runTrans(transMeta);
}/**
* 运行转换
*
* @param transMeta
* @throws KettleException
*/
private static void runTrans(TransMeta transMeta) throws KettleException {
Trans trans = new Trans(transMeta);
trans.execute(null);// 执行转换
trans.waitUntilFinished(); // 等待转换执行结束
}/**
* 创建步骤:(输入:表输入)
*
* @param transMeta
* @return
*/
private static StepMeta createStep1(TransMeta transMeta) {
// 新建一个表输入步骤(TableInputMeta)
TableInputMeta tableInputMeta = new TableInputMeta();
// 设置步骤1的数据库连接
tableInputMeta.setDatabaseMeta(transMeta.findDatabase("fromDbName"));
// 设置步骤1中的sql
tableInputMeta.setSQL("SELECT id1 as id2 ,name1 as name2 FROM from_user");
// 设置步骤名称
StepMeta step1 = new StepMeta("step1name", tableInputMeta);
return step1;
}/**
* 创建步骤:(输出:插入/更新)
*
* @param transMeta
* @return
*/
private static StepMeta createStep2(TransMeta transMeta) {
// 新建一个插入/更新步骤
InsertUpdateMeta insertUpdateMeta = new InsertUpdateMeta();
// 设置步骤2的数据库连接
insertUpdateMeta.setDatabaseMeta(transMeta.findDatabase("toDbName"));
// 设置目标表
insertUpdateMeta.setTableName("to_user");
// 设置用来查询的关键字
insertUpdateMeta.setKeyLookup(new String[] {"id2"});
insertUpdateMeta.setKeyCondition(new String[] {"="});
insertUpdateMeta.setKeyStream(new String[] {"id2"});
insertUpdateMeta.setKeyStream2(new String[] {""});// 一定要加上
// 设置要更新的字段
String[] updatelookup = {"id2", "name2"};
String[] updateStream = {"id2", "name2"};
Boolean[] updateOrNot = {false, true};
// 设置表字段
insertUpdateMeta.setUpdateLookup(updatelookup);
// 设置流字段
insertUpdateMeta.setUpdateStream(updateStream);
// 设置是否更新
insertUpdateMeta.setUpdate(updateOrNot);
// 设置步骤2的名称
StepMeta step2 = new StepMeta("step2name", insertUpdateMeta);
return step2;
}/**
* 创建转换
*
* @return
*/
private static TransMeta createTrans() {
TransMeta transMeta = new TransMeta();
// 设置转化的名称
transMeta.setName("cgmTransName");
// 添加转换的数据库连接
transMeta.addDatabase(new DatabaseMeta("fromDbName", "mysql", "Native(JDBC)", "127.0.0.1",
"fromdb?useSSL=false", "3306", "root", "root"));
transMeta.addDatabase(new DatabaseMeta("toDbName", "mysql", "Native(JDBC)", "127.0.0.1", "todb?useSSL=false",
"3306", "root", "root"));
return transMeta;
}/**
* 创建节点连接
*
* @param step1
* @param step2
* @return
*/
private static TransHopMeta createHop(StepMeta step1, StepMeta step2) {
// 设置起始步骤和目标步骤,把两个步骤关联起来
TransHopMeta transHopMeta = new TransHopMeta(step1, step2);
return transHopMeta;
}/**
* 定义一个转换,但是还没有保存到资源库
*
* @return
* @throws KettleException
*/
private static TransMeta generateTrans() throws KettleException {
TransMeta transMeta = createTrans();
// 创建步骤1并添加到转换中
StepMeta step1 = createStep1(transMeta);
transMeta.addStep(step1);
// 创建步骤2并添加到转换中
StepMeta step2 = createStep2(transMeta);
transMeta.addStep(step2);
// 创建hop连接并添加hop
TransHopMeta TransHopMeta = createHop(step1, step2);
transMeta.addTransHop(TransHopMeta);
return transMeta;
}}
但是需要注意的是这个转换只是临时的,运行完毕就消失了。并没有保存到kettle的资源库中。
那么如果想把这个临时的转换固定到资源库中该如何做呢?
package test;
import org.pentaho.di.core.KettleEnvironment;
import org.pentaho.di.core.database.DatabaseMeta;
import org.pentaho.di.core.exception.KettleException;
import org.pentaho.di.repository.RepositoryDirectoryInterface;
import org.pentaho.di.repository.kdr.KettleDatabaseRepository;
import org.pentaho.di.repository.kdr.KettleDatabaseRepositoryMeta;
import org.pentaho.di.trans.Trans;
import org.pentaho.di.trans.TransHopMeta;
import org.pentaho.di.trans.TransMeta;
import org.pentaho.di.trans.step.StepMeta;
import org.pentaho.di.trans.steps.insertupdate.InsertUpdateMeta;
import org.pentaho.di.trans.steps.tableinput.TableInputMeta;/**
* @author cgm
* @date 2019年7月8日
*/
public class KettleTest {
public static void main(String[] args) throws Exception {
KettleEnvironment.init();
TransMeta transMeta = generateTrans();
KettleDatabaseRepository kettleDatabaseRepository = RepositoryCon();
saveTrans(kettleDatabaseRepository, transMeta);
}/**
* 运行转换
*
* @param transMeta
* @throws KettleException
*/
private static void runTrans(TransMeta transMeta) throws KettleException {
Trans trans = new Trans(transMeta);
trans.execute(null);// 执行转换
trans.waitUntilFinished(); // 等待转换执行结束
}/**
* 创建步骤:(输入:表输入)
*
* @param transMeta
* @return
*/
private static StepMeta createStep1(TransMeta transMeta) {
// 新建一个表输入步骤(TableInputMeta)
TableInputMeta tableInputMeta = new TableInputMeta();
// 设置步骤1的数据库连接
tableInputMeta.setDatabaseMeta(transMeta.findDatabase("fromDbName"));
// 设置步骤1中的sql
tableInputMeta.setSQL("SELECT id1 as id2 ,name1 as name2 FROM from_user");
// 设置步骤名称
StepMeta step1 = new StepMeta("step1name", tableInputMeta);
return step1;
}/**
* 创建步骤:(输出:插入/更新)
*
* @param transMeta
* @return
*/
private static StepMeta createStep2(TransMeta transMeta) {
// 新建一个插入/更新步骤
InsertUpdateMeta insertUpdateMeta = new InsertUpdateMeta();
// 设置步骤2的数据库连接
insertUpdateMeta.setDatabaseMeta(transMeta.findDatabase("toDbName"));
// 设置目标表
insertUpdateMeta.setTableName("to_user");
// 设置用来查询的关键字
insertUpdateMeta.setKeyLookup(new String[] {"id2"});
insertUpdateMeta.setKeyCondition(new String[] {"="});
insertUpdateMeta.setKeyStream(new String[] {"id2"});
insertUpdateMeta.setKeyStream2(new String[] {""});// 一定要加上
// 设置要更新的字段
String[] updatelookup = {"id2", "name2"};
String[] updateStream = {"id2", "name2"};
Boolean[] updateOrNot = {false, true};
// 设置表字段
insertUpdateMeta.setUpdateLookup(updatelookup);
// 设置流字段
insertUpdateMeta.setUpdateStream(updateStream);
// 设置是否更新
insertUpdateMeta.setUpdate(updateOrNot);
// 设置步骤2的名称
StepMeta step2 = new StepMeta("step2name", insertUpdateMeta);
return step2;
}/**
* 创建转换
*
* @return
*/
private static TransMeta createTrans() {
TransMeta transMeta = new TransMeta();
// 设置转化的名称
transMeta.setName("cgmTransName");
// 添加转换的数据库连接
transMeta.addDatabase(new DatabaseMeta("fromDbName", "mysql", "Native(JDBC)", "127.0.0.1",
"fromdb?useSSL=false", "3306", "root", "root"));
transMeta.addDatabase(new DatabaseMeta("toDbName", "mysql", "Native(JDBC)", "127.0.0.1", "todb?useSSL=false",
"3306", "root", "root"));
return transMeta;
}/**
* 创建节点连接
*
* @param step1
* @param step2
* @return
*/
private static TransHopMeta createHop(StepMeta step1, StepMeta step2) {
// 设置起始步骤和目标步骤,把两个步骤关联起来
TransHopMeta transHopMeta = new TransHopMeta(step1, step2);
return transHopMeta;
}/**
* 定义一个转换,但是还没有保存到资源库
*
* @return
* @throws KettleException
*/
private static TransMeta generateTrans() throws KettleException {
TransMeta transMeta = createTrans();
// 创建步骤1并添加到转换中
StepMeta step1 = createStep1(transMeta);
transMeta.addStep(step1);
// 创建步骤2并添加到转换中
StepMeta step2 = createStep2(transMeta);
transMeta.addStep(step2);
// 创建hop连接并添加hop
TransHopMeta TransHopMeta = createHop(step1, step2);
transMeta.addTransHop(TransHopMeta);
return transMeta;
}/**
* 连接到资源库
*/
private static KettleDatabaseRepository RepositoryCon() throws KettleException {
// 初始化环境
if (!KettleEnvironment.isInitialized()) {
try {
KettleEnvironment.init();
} catch (KettleException e) {
e.printStackTrace();
}
}
// 数据库连接元对象
// (kettle数据库连接名称(KETTLE工具右上角显示),资源库类型,连接方式,IP,数据库名,端口,用户名,密码) //cgmRepositoryConn
DatabaseMeta databaseMeta = new DatabaseMeta("cgmRepository", "mysql", "Native(JDBC)", "127.0.0.1",
"cgmrepositorydb", "3306", "root", "root");
// 数据库形式的资源库元对象
KettleDatabaseRepositoryMeta kettleDatabaseRepositoryMeta = new KettleDatabaseRepositoryMeta();
kettleDatabaseRepositoryMeta.setConnection(databaseMeta);
// 数据库形式的资源库对象
KettleDatabaseRepository kettleDatabaseRepository = new KettleDatabaseRepository();
// 用资源库元对象初始化资源库对象
kettleDatabaseRepository.init(kettleDatabaseRepositoryMeta);
// 连接到资源库
kettleDatabaseRepository.connect("admin", "admin");// 默认的连接资源库的用户名和密码
if (kettleDatabaseRepository.isConnected()) {
System.out.println("连接成功");
return kettleDatabaseRepository;
} else {
System.out.println("连接失败");
return null;
}
}/**
* 保存转换到资源库
*
* @param kettleDatabaseRepository
* @param transMeta
* @throws Exception
*/
private static void saveTrans(KettleDatabaseRepository kettleDatabaseRepository, TransMeta transMeta)
throws Exception {
RepositoryDirectoryInterface dir = kettleDatabaseRepository.loadRepositoryDirectoryTree().findDirectory("/");
transMeta.setRepositoryDirectory(dir);
kettleDatabaseRepository.save(transMeta, null);
}}
然后去资源库中查看,已经多了一条转换记录
参考资料:
kettle demo12 通过JAVA创建trans并保存到数据库资源库 https://my.oschina.net/feiyang2017/blog/3033705