一、认识数据库连接
在Kettle的转换和作业任务中,数据连接是一个很重要的功能,所有涉及数据库的交换都离不开它,它是定义了数据库连接关键信息,本篇针对这个功能讲解如何实现二次开发。
二、数据表设计说明
- R_DATABASE : 基本信息表;
- R_DATABASE_ATTRIBUTE: 数据库连接属性表;
- R_DATABASE_CONTYPE: 数据库连接方式;
- R_DATABASE_TYPE: 数据库连接类型;
- R_STEP_DATABASE: 交换步骤关联关系表
- R_JOBENTRY_DATABASE:作业关联关系表
1.表:R_DATABASE
序号 | 列名 | 数据类型 | 长度 | 主键 | 空 | 列说明 |
1 | ID_DATABASE | NUMBER | √ | id | ||
2 | NAME | VARCHAR2 | 255 | √ | 连接名称 | |
3 | ID_DATABASE_TYPE | NUMBER | √ | 连接类型 | ||
4 | ID_DATABASE_CONTYPE | NUMBER | √ | 连接方式 | ||
5 | HOST_NAME | VARCHAR2 | 255 | √ | 主机名称 | |
6 | DATABASE_NAME | CLOB | 4000 | √ | 数据库名称 | |
7 | PORT | NUMBER | √ | 端口 | ||
8 | USERNAME | VARCHAR2 | 255 | √ | 用户名 | |
9 | PASSWORD | VARCHAR2 | 255 | √ | 密码 | |
10 | SERVERNAME | VARCHAR2 | 255 | √ | ||
11 | DATA_TBS | VARCHAR2 | 255 | √ | ||
12 | INDEX_TBS | VARCHAR2 | 255 | √ |
2.表:R_DATABASE_ATTRIBUTE
序号 | 列名 | 数据类型 | 长度 | 主键 | 空 | 列说明 |
1 | ID_DATABASE_ATTRIBUTE | NUMBER | √ | id | ||
2 | ID_DATABASE | NUMBER | √ | 数据库连接ID | ||
3 | CODE | VARCHAR2 | 255 | √ | 属性code | |
4 | VALUE_STR | CLOB | 4000 | √ | 属性值 |
3.表:R_DATABASE_CONTYPE
序号 | 列名 | 数据类型 | 长度 | 主键 | 允许空 | 列说明 |
1 | ID_DATABASE_CONTYPE | NUMBER | √ | id | ||
2 | CODE | VARCHAR2 | 255 | √ | 编码 | |
3 | DESCRIPTION | VARCHAR2 | 255 | √ | 描述 |
4.表:R_DATABASE_TYPE
序号 | 列名 | 数据类型 | 长度 | 主键 | 允许空 | 列说明 |
1 | ID_DATABASE_TYPE | NUMBER | √ | id | ||
2 | CODE | VARCHAR2 | 255 | √ | 编码 | |
3 | DESCRIPTION | VARCHAR2 | 255 | √ | 描述 |
5.R_STEP_DATABASE
序号 | 列名 | 数据类型 | 长度 | 主键 | 允许空 | 列说明 |
1 | ID_TRANSFORMATION | NUMBER | √ | id | ||
2 | ID_STEP | NUMBER | 转换部署ID | |||
3 | ID_DATABASE | NUMBER | 数据库连接ID |
6.R_JOBENTRY_DATABASE
序号 | 列名 | 数据类型 | 长度 | 主键 | 允许空 | 列说明 |
1 | ID_JOB | NUMBER | √ | id | ||
2 | ID_JOBENTRY | NUMBER | 转换部署ID | |||
3 | ID_DATABASE | NUMBER | 数据库连接ID |
三、功能实现
后台实现的具体代码
1.数据库连接列表
用列表的方式呈现数据库连接信息
代码实现 API readDatabases
AbstractRepository abstractRepository = repositoryService.getAbstractRepository(repositoryId);
//获取资源库中数据库连接列表
List list=abstractRepository.readDatabases();
//进行组装数据返回
List databaseList= new ArrayList<>();
for ( DatabaseMeta databaseMeta : list){
DataMap dataMap=new DataMap();
dataMap.put("databaseId",databaseMeta.getObjectId().getId());
dataMap.put("name",databaseMeta.getName());
dataMap.put("hostName",databaseMeta.getHostname());
dataMap.put("databaseName",databaseMeta.getDatabaseName());
dataMap.put("databaseType",databaseMeta.getPluginId());
databaseList.add(dataMap);
}
2.数据连接详情
获取 DatabaseMeta 代码实现
public Result Open(int repositoryId,int databaseId) {
try {
DatabaseMeta databaseMeta=new DatabaseMeta();
ObjectId objectId = new LongObjectId(databaseId);
if (databaseId==0){
//新增
databaseMeta.setObjectId(objectId);
}else {
//连接资源库
AbstractRepository abstractRepository = repositoryService.getAbstractRepository(repositoryId);
//加载数据库连接信息
databaseMeta = abstractRepository.loadDatabaseMeta(objectId, null);
}
//进行自定义编码转换为json
JSONObject jsonObject = DatabaseCodec.encode(databaseMeta);
return Result.success(jsonObject);
} catch (Exception e) {
LOGGER.error("list", e);
return Result.error("发生异常,请查询日志");
}
}
测试连接代码实现
public Result test(String databaseInfo) throws IOException, KettleDatabaseException {
JSONObject jsonObject = JSONObject.fromObject(databaseInfo);
DatabaseMeta dbinfo = DatabaseCodec.decode(jsonObject);
String[] remarks = dbinfo.checkParameters();
String reportMessage="";
if ( remarks.length == 0 ) {
reportMessage = dbinfo.testConnection();
}
return Result.success(StringEscapeHelper.encode(reportMessage));
}
3.删除数据链接:API delDatabase,delDatabaseAttributes
AbstractRepository abstractRepository = repositoryService.getAbstractRepository(transRepositoryId);
KettleDatabaseRepository repository=(KettleDatabaseRepository) abstractRepository ;
ObjectId id=new LongObjectId(databaseId);
//删除
repository.databaseDelegate.delDatabase(id);
repository.databaseDelegate.delDatabaseAttributes(id);
//提交
repository.commit();
说明:删除这里采用API接口调用技术
- 通过APIdelDatabase按databaseId 删除数据链接;
- 通过APIdelDatabaseAttributes按databaseId 删除数据链接属性;
- 删除的时候API接口会进行判断是否被交换或作业是否在引用,如果删除正在引用的数据库连接就会抛出异常。
- 操作完后要进行commit
总结:
Kettle 目前没有api的相关文档,只能自己慢慢摸索,由于篇幅问题不能贴出全部代码,整个开发采用了前后端分离模式,前端代码已经公开分享出去,详细见vue实战课程二(登录、主界面页面和导航菜单的实现),后端代码(java)部分后续会公开分享,有兴趣的可以持续关注,一块探究。
有个问题一直没有研究清楚,就是在api开发过程中数据库连接插件如何通过外部的方式进行加载,通过设置kettlePluginPackages参数也没有解决问题,只能采用在pom引用依赖方式进行解决。