mirror of
https://gitee.com/dromara/dbswitch.git
synced 2025-09-11 06:29:06 +00:00
@@ -16,18 +16,20 @@ import lombok.Getter;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum ResultCode {
|
public enum ResultCode {
|
||||||
|
|
||||||
SUCCESS(0,"操作成功"),
|
SUCCESS(0, "操作成功"),
|
||||||
ERROR_INTERNAL_ERROR(1,"内部错误"),
|
ERROR_INTERNAL_ERROR(1, "内部错误"),
|
||||||
ERROR_INVALID_ARGUMENT(2,"无效参数"),
|
ERROR_INVALID_ARGUMENT(2, "无效参数"),
|
||||||
ERROR_RESOURCE_NOT_EXISTS(3,"资源不存在"),
|
ERROR_RESOURCE_NOT_EXISTS(3, "资源不存在"),
|
||||||
ERROR_RESOURCE_ALREADY_EXISTS(4,"资源已存在"),
|
ERROR_RESOURCE_ALREADY_EXISTS(4, "资源已存在"),
|
||||||
ERROR_RESOURCE_NOT_DEPLOY(5,"资源未发布"),
|
ERROR_RESOURCE_NOT_DEPLOY(5, "资源未发布"),
|
||||||
ERROR_RESOURCE_HAS_DEPLOY(6,"资源已发布"),
|
ERROR_RESOURCE_HAS_DEPLOY(6, "资源已发布"),
|
||||||
ERROR_USER_NOT_EXISTS(7,"用户不存在"),
|
ERROR_USER_NOT_EXISTS(7, "用户不存在"),
|
||||||
ERROR_USER_PASSWORD_WRONG(8,"密码错误"),
|
ERROR_USER_PASSWORD_WRONG(8, "密码错误"),
|
||||||
|
ERROR_INVALID_JDBC_URL(9, "JDBC连接的URL格式不正确"),
|
||||||
|
ERROR_CANNOT_CONNECT_REMOTE(10, "远程地址不可达"),
|
||||||
|
|
||||||
ERROR_ACCESS_FORBIDDEN(403,"无效的登陆凭证"),
|
ERROR_ACCESS_FORBIDDEN(403, "无效的登陆凭证"),
|
||||||
ERROR_TOKEN_EXPIRED(404,"登录凭证已失效"),
|
ERROR_TOKEN_EXPIRED(404, "登录凭证已失效"),
|
||||||
;
|
;
|
||||||
|
|
||||||
private int code;
|
private int code;
|
||||||
|
@@ -23,6 +23,7 @@ import com.gitee.dbswitch.admin.model.response.DatabaseTypeDetailResponse;
|
|||||||
import com.gitee.dbswitch.admin.model.response.DbConnectionDetailResponse;
|
import com.gitee.dbswitch.admin.model.response.DbConnectionDetailResponse;
|
||||||
import com.gitee.dbswitch.admin.model.response.DbConnectionNameResponse;
|
import com.gitee.dbswitch.admin.model.response.DbConnectionNameResponse;
|
||||||
import com.gitee.dbswitch.admin.type.SupportDbTypeEnum;
|
import com.gitee.dbswitch.admin.type.SupportDbTypeEnum;
|
||||||
|
import com.gitee.dbswitch.admin.util.JDBCURL;
|
||||||
import com.gitee.dbswitch.admin.util.PageUtil;
|
import com.gitee.dbswitch.admin.util.PageUtil;
|
||||||
import com.gitee.dbswitch.common.constant.DatabaseTypeEnum;
|
import com.gitee.dbswitch.common.constant.DatabaseTypeEnum;
|
||||||
import com.gitee.dbswitch.core.service.IMetaDataService;
|
import com.gitee.dbswitch.core.service.IMetaDataService;
|
||||||
@@ -31,8 +32,10 @@ import java.util.ArrayList;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
|
import org.apache.commons.lang.StringUtils;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
@@ -48,7 +51,7 @@ public class DbConnectionService {
|
|||||||
detail.setId(type.getId());
|
detail.setId(type.getId());
|
||||||
detail.setType(type.getName().toUpperCase());
|
detail.setType(type.getName().toUpperCase());
|
||||||
detail.setDriver(type.getDriver());
|
detail.setDriver(type.getDriver());
|
||||||
detail.setTemplate(type.getTemplate());
|
detail.setTemplate(StringUtils.join(type.getUrl(), ","));
|
||||||
|
|
||||||
lists.add(detail);
|
lists.add(detail);
|
||||||
}
|
}
|
||||||
@@ -80,11 +83,38 @@ public class DbConnectionService {
|
|||||||
return Result.failed(ResultCode.ERROR_RESOURCE_NOT_EXISTS, "id=" + id);
|
return Result.failed(ResultCode.ERROR_RESOURCE_NOT_EXISTS, "id=" + id);
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseTypeEnum dbType = DatabaseTypeEnum.valueOf(dbConn.getType().getName().toUpperCase());
|
SupportDbTypeEnum supportDbType = SupportDbTypeEnum
|
||||||
|
.valueOf(dbConn.getType().getName().toUpperCase());
|
||||||
|
for (String pattern : supportDbType.getUrl()) {
|
||||||
|
final Matcher matcher = JDBCURL.getPattern(pattern).matcher(dbConn.getUrl());
|
||||||
|
if (!matcher.matches()) {
|
||||||
|
if (1 == supportDbType.getUrl().length) {
|
||||||
|
return Result.failed(ResultCode.ERROR_INVALID_JDBC_URL, dbConn.getUrl());
|
||||||
|
} else {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String host = matcher.group("host");
|
||||||
|
String port = matcher.group("port");
|
||||||
|
if (null == port) {
|
||||||
|
port = String.valueOf(supportDbType.getPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!JDBCURL.reachable(host, port)) {
|
||||||
|
return Result.failed(ResultCode.ERROR_CANNOT_CONNECT_REMOTE, dbConn.getUrl());
|
||||||
|
}
|
||||||
|
|
||||||
|
DatabaseTypeEnum prd = DatabaseTypeEnum.valueOf(dbConn.getType().getName().toUpperCase());
|
||||||
IMetaDataService metaDataService = new MigrationMetaDataServiceImpl();
|
IMetaDataService metaDataService = new MigrationMetaDataServiceImpl();
|
||||||
metaDataService.setDatabaseConnection(dbType);
|
metaDataService.setDatabaseConnection(prd);
|
||||||
metaDataService.testQuerySQL(dbConn.getUrl(), dbConn.getUsername(), dbConn.getPassword(),
|
metaDataService.testQuerySQL(
|
||||||
dbConn.getType().getSql());
|
dbConn.getUrl(),
|
||||||
|
dbConn.getUsername(),
|
||||||
|
dbConn.getPassword(),
|
||||||
|
dbConn.getType().getSql()
|
||||||
|
);
|
||||||
|
}
|
||||||
return Result.success();
|
return Result.success();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -17,28 +17,31 @@ import org.springframework.util.StringUtils;
|
|||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public enum SupportDbTypeEnum {
|
public enum SupportDbTypeEnum {
|
||||||
|
|
||||||
MYSQL(1, "mysql", "com.mysql.jdbc.Driver", "/* ping */ SELECT 1",
|
MYSQL(1, "mysql", "com.mysql.jdbc.Driver", 3306, "/* ping */ SELECT 1",
|
||||||
"jdbc:mysql://{host}:{port>/{name}?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&tinyInt1isBit=false"),
|
new String[]{"jdbc:mysql://{host}[:{port}]/[{database}][\\?{params}]"}),
|
||||||
MARIADB(2, "mariadb", "org.mariadb.jdbc.Driver", "SELECT 1",
|
MARIADB(2, "mariadb", "org.mariadb.jdbc.Driver", 3306, "SELECT 1",
|
||||||
"jdbc:mariadb://{host}:{port}/{name}?useUnicode=true&characterEncoding=utf-8&useSSL=false&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&nullCatalogMeansCurrent=true&tinyInt1isBit=false"),
|
new String[]{"jdbc:mariadb://{host}[:{port}]/[{database}][\\?{params}]"}),
|
||||||
ORACLE(3, "oracle", "oracle.jdbc.driver.OracleDriver", "SELECT 'Hello' from DUAL",
|
ORACLE(3, "oracle", "oracle.jdbc.driver.OracleDriver", 1521, "SELECT 'Hello' from DUAL",
|
||||||
"jdbc:oracle:thin:@{host}:{port}:{name}"),
|
new String[]{"jdbc:oracle:thin:@{host}:{port}:{name}",
|
||||||
SQLSERVER(4, "sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver", "SELECT 1+2 as a",
|
"jdbc:oracle:thin:@//{host}[:{port}]/{name}"}),
|
||||||
"jdbc:sqlserver://{host}:{port};DatabaseName={name}"),
|
SQLSERVER(4, "sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver", 1433, "SELECT 1+2 as a",
|
||||||
POSTGRESQL(5, "postgresql", "org.postgresql.Driver", "SELECT 1",
|
new String[]{"jdbc:sqlserver://{host}[:{port}][;databaseName={database}][;{params}]"}),
|
||||||
"jdbc:postgresql://{host}:{port}/{name}"),
|
POSTGRESQL(5, "postgresql", "org.postgresql.Driver", 5432, "SELECT 1",
|
||||||
DB2(6, "db2", "com.ibm.db2.jcc.DB2Driver", "SELECT 1 FROM SYSIBM.SYSDUMMY1",
|
new String[]{"jdbc:postgresql://{host}[:{port}]/[{database}][\\?{params}]"}),
|
||||||
"jdbc:db2://{host}:{port}/{name}:driverType=4;fullyMaterializeLobData=true;fullyMaterializeInputStreams=true;progressiveStreaming=2;progresssiveLocators=2;"),
|
DB2(6, "db2", "com.ibm.db2.jcc.DB2Driver", 50000, "SELECT 1 FROM SYSIBM.SYSDUMMY1",
|
||||||
DM(7, "dm", "dm.jdbc.driver.DmDriver", "SELECT 'Hello' from DUAL", "jdbc:dm://{host}:{port}"),
|
new String[]{"jdbc:db2://{host}:{port}/{database}[:{params}]"}),
|
||||||
KINGBASE(8, "kingbase", "com.kingbase8.Driver", "SELECT 1",
|
DM(7, "dm", "dm.jdbc.driver.DmDriver", 5236, "SELECT 'Hello' from DUAL",
|
||||||
"jdbc:kingbase8://{host}:{port}/{name}"),
|
new String[]{"jdbc:dm://{host}:{port}[/{database}][\\?{params}]"}),
|
||||||
|
KINGBASE(8, "kingbase", "com.kingbase8.Driver", 54321, "SELECT 1",
|
||||||
|
new String[]{"jdbc:kingbase8://{host}[:{port}]/[{database}][\\?{params}]"}),
|
||||||
;
|
;
|
||||||
|
|
||||||
private int id;
|
private int id;
|
||||||
private String name;
|
private String name;
|
||||||
private String driver;
|
private String driver;
|
||||||
|
private int port;
|
||||||
private String sql;
|
private String sql;
|
||||||
private String template;
|
private String[] url;
|
||||||
|
|
||||||
public static SupportDbTypeEnum of(String name) {
|
public static SupportDbTypeEnum of(String name) {
|
||||||
if (!StringUtils.isEmpty(name)) {
|
if (!StringUtils.isEmpty(name)) {
|
||||||
|
@@ -0,0 +1,297 @@
|
|||||||
|
// Copyright tang. All rights reserved.
|
||||||
|
// https://gitee.com/inrgihc/dbswitch
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style license
|
||||||
|
//
|
||||||
|
// Author: tang (inrgihc@126.com)
|
||||||
|
// Date : 2020/1/2
|
||||||
|
// Location: beijing , china
|
||||||
|
/////////////////////////////////////////////////////////////
|
||||||
|
package com.gitee.dbswitch.admin.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.util.function.Function;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JDBC-URL参数提取工具类
|
||||||
|
*
|
||||||
|
* @author tang
|
||||||
|
* @date 2021-11-20 22:54:21
|
||||||
|
* @since 1.0
|
||||||
|
*/
|
||||||
|
public class JDBCURL {
|
||||||
|
|
||||||
|
public static final String PROP_HOST = "host"; //$NON-NLS-1$
|
||||||
|
public static final String PROP_PORT = "port"; //$NON-NLS-1$
|
||||||
|
public static final String PROP_DATABASE = "database"; //$NON-NLS-1$
|
||||||
|
public static final String PROP_SERVER = "server"; //$NON-NLS-1$
|
||||||
|
public static final String PROP_PARAMS = "params"; //$NON-NLS-1$
|
||||||
|
public static final String PROP_FOLDER = "folder"; //$NON-NLS-1$
|
||||||
|
public static final String PROP_FILE = "file"; //$NON-NLS-1$
|
||||||
|
public static final String PROP_USER = "user"; //$NON-NLS-1$
|
||||||
|
public static final String PROP_PASSWORD = "password"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
private static String getPropertyRegex(String property) {
|
||||||
|
switch (property) {
|
||||||
|
case PROP_FOLDER:
|
||||||
|
case PROP_FILE:
|
||||||
|
case PROP_PARAMS:
|
||||||
|
return ".+?";
|
||||||
|
default:
|
||||||
|
return "[\\\\w\\\\-_.~]+";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String replaceAll(String input, String regex, Function<Matcher, String> replacer) {
|
||||||
|
final Matcher matcher = Pattern.compile(regex).matcher(input);
|
||||||
|
final StringBuffer sb = new StringBuffer();
|
||||||
|
while (matcher.find()) {
|
||||||
|
matcher.appendReplacement(sb, replacer.apply(matcher));
|
||||||
|
}
|
||||||
|
matcher.appendTail(sb);
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Pattern getPattern(String sampleUrl) {
|
||||||
|
String pattern = sampleUrl;
|
||||||
|
pattern = replaceAll(pattern, "\\[(.*?)]", m -> "\\\\E(?:\\\\Q" + m.group(1) + "\\\\E)?\\\\Q");
|
||||||
|
pattern = replaceAll(pattern, "\\{(.*?)}",
|
||||||
|
m -> "\\\\E(\\?<\\\\Q" + m.group(1) + "\\\\E>" + getPropertyRegex(m.group(1)) + ")\\\\Q");
|
||||||
|
pattern = "^\\Q" + pattern + "\\E$";
|
||||||
|
return Pattern.compile(pattern);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据主机地址与端口号检查可达性
|
||||||
|
*
|
||||||
|
* @param host 主机地址
|
||||||
|
* @param port 端口号
|
||||||
|
* @return 成功返回true,否则为false
|
||||||
|
*/
|
||||||
|
public static boolean reachable(String host, String port) {
|
||||||
|
try {
|
||||||
|
InetAddress address = InetAddress.getByName(host);
|
||||||
|
if (!address.isReachable(1500)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
try (Socket socket = new Socket()) {
|
||||||
|
socket.connect(new InetSocketAddress(host, Integer.parseInt(port)), 1500);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 测试代码
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 1、teradata数据库
|
||||||
|
// jdbc:teradata://localhost/DATABASE=test,DBS_PORT=1234,CLIENT_CHARSET=EUC_CN,TMODE=TERA,CHARSET=ASCII,LOB_SUPPORT=true
|
||||||
|
final Matcher matcher0 = JDBCURL
|
||||||
|
.getPattern("jdbc:teradata://{host}/DATABASE={database},DBS_PORT={port}[,{params}]")
|
||||||
|
.matcher(
|
||||||
|
"jdbc:teradata://localhost/DATABASE=test,DBS_PORT=1234,CLIENT_CHARSET=EUC_CN,TMODE=TERA,CHARSET=ASCII,LOB_SUPPORT=true");
|
||||||
|
if (matcher0.matches()) {
|
||||||
|
System.out.println("teradata host:" + matcher0.group("host"));
|
||||||
|
System.out.println("teradata port:" + matcher0.group("port"));
|
||||||
|
System.out.println("teradata database:" + matcher0.group("database"));
|
||||||
|
String params = matcher0.group("params");
|
||||||
|
if (null != params) {
|
||||||
|
String[] pairs = params.split(",");
|
||||||
|
for (String pair : pairs) {
|
||||||
|
System.out.println("teradata params:" + pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("error for teradata!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2、PostgreSQL数据库
|
||||||
|
// jdbc:postgresql://localhost:5432/dvdrental?currentSchema=test&ssl=true
|
||||||
|
// https://jdbc.postgresql.org/documentation/head/connect.html
|
||||||
|
final Matcher matcher1 = JDBCURL
|
||||||
|
.getPattern("jdbc:postgresql://{host}[:{port}]/[{database}][\\?{params}]")
|
||||||
|
.matcher("jdbc:postgresql://localhost:5432/dvdrental?currentSchema=test&ssl=true");
|
||||||
|
if (matcher1.matches()) {
|
||||||
|
System.out.println("postgresql host:" + matcher1.group("host"));
|
||||||
|
System.out.println("postgresql port:" + matcher1.group("port"));
|
||||||
|
System.out.println("postgresql database:" + matcher1.group("database"));
|
||||||
|
String params = matcher1.group("params");
|
||||||
|
if (null != params) {
|
||||||
|
String[] pairs = params.split("&");
|
||||||
|
for (String pair : pairs) {
|
||||||
|
System.out.println("postgresql params:" + pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("error for postgresql!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3、Oracle数据库
|
||||||
|
// oracle sid 方式
|
||||||
|
final Matcher matcher2 = JDBCURL.getPattern("jdbc:oracle:thin:@{host}[:{port}]:{sid}")
|
||||||
|
.matcher("jdbc:oracle:thin:@localhost:1521:orcl");
|
||||||
|
if (matcher2.matches()) {
|
||||||
|
System.out.println("oracle sid host:" + matcher2.group("host"));
|
||||||
|
System.out.println("oracle sid port:" + matcher2.group("port"));
|
||||||
|
System.out.println("oracle sid name:" + matcher2.group("sid"));
|
||||||
|
} else {
|
||||||
|
System.out.println("error for oracle sid!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// oracle service name 方式
|
||||||
|
final Matcher matcher2_1 = JDBCURL.getPattern("jdbc:oracle:thin:@//{host}[:{port}]/{name}")
|
||||||
|
.matcher("jdbc:oracle:thin:@//localhost:1521/orcl.city.com");
|
||||||
|
if (matcher2_1.matches()) {
|
||||||
|
System.out.println("oracle ServiceName host:" + matcher2_1.group("host"));
|
||||||
|
System.out.println("oracle ServiceName port:" + matcher2_1.group("port"));
|
||||||
|
System.out.println("oracle ServiceName name:" + matcher2_1.group("name"));
|
||||||
|
} else {
|
||||||
|
System.out.println("error for oracle ServiceName!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// oracle TNSName 方式不支持
|
||||||
|
// jdbc:oracle:thin:@(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=192.168.16.91)(PORT=1521)))(CONNECT_DATA=(SERVICE_NAME=orcl)))
|
||||||
|
// ..............................
|
||||||
|
|
||||||
|
// 4、MySQL数据库
|
||||||
|
// jdbc:mysql://172.17.2.10:3306/test?useUnicode=true&useSSL=false
|
||||||
|
final Matcher matcher3 = JDBCURL
|
||||||
|
.getPattern("jdbc:mysql://{host}[:{port}]/[{database}][\\?{params}]")
|
||||||
|
.matcher("jdbc:mysql://localhost:3306/test_demo?useUnicode=true&useSSL=false");
|
||||||
|
if (matcher3.matches()) {
|
||||||
|
System.out.println("mysql host:" + matcher3.group("host"));
|
||||||
|
System.out.println("mysql port:" + matcher3.group("port"));
|
||||||
|
System.out.println("mysql database:" + matcher3.group("database"));
|
||||||
|
String params = matcher3.group("params");
|
||||||
|
if (null != params) {
|
||||||
|
String[] pairs = params.split("&");
|
||||||
|
for (String pair : pairs) {
|
||||||
|
System.out.println("mysql params:" + pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("error for mysql!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5、MariaDB数据库
|
||||||
|
// 同Mysql的jdbc-url
|
||||||
|
final Matcher matcher4 = JDBCURL
|
||||||
|
.getPattern("jdbc:mariadb://{host}[:{port}]/[{database}][\\?{params}]")
|
||||||
|
.matcher("jdbc:mariadb://localhost:3306/test_demo");
|
||||||
|
if (matcher4.matches()) {
|
||||||
|
System.out.println("mariadb host:" + matcher4.group("host"));
|
||||||
|
System.out.println("mariadb port:" + matcher4.group("port"));
|
||||||
|
System.out.println("mariadb database:" + matcher4.group("database"));
|
||||||
|
String params = matcher4.group("params");
|
||||||
|
if (null != params) {
|
||||||
|
String[] pairs = params.split("&");
|
||||||
|
for (String pair : pairs) {
|
||||||
|
System.out.println("mysql params:" + pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("error for mariadb!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6、Microsoft SQLServer数据库
|
||||||
|
// jdbc:sqlserver://localhost:1433;databaseName=AdventureWorks;user=MyUserName;password=123456;
|
||||||
|
final Matcher matcher5 = JDBCURL
|
||||||
|
.getPattern("jdbc:sqlserver://{host}[:{port}][;databaseName={database}][;{params}]")
|
||||||
|
.matcher("jdbc:sqlserver://localhost:1433;databaseName=master;user=MyUserName");
|
||||||
|
if (matcher5.matches()) {
|
||||||
|
System.out.println("sqlserver host:" + matcher5.group("host"));
|
||||||
|
System.out.println("sqlserver port:" + matcher5.group("port"));
|
||||||
|
System.out.println("sqlserver database:" + matcher5.group("database"));
|
||||||
|
String params = matcher5.group("params");
|
||||||
|
if (null != params) {
|
||||||
|
String[] pairs = params.split(";");
|
||||||
|
for (String pair : pairs) {
|
||||||
|
System.out.println("sqlserver params:" + pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("error for sqlserver!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 7、人大金仓数据库
|
||||||
|
// 同postgresql的jdbc-url
|
||||||
|
final Matcher matcher6 = JDBCURL
|
||||||
|
.getPattern("jdbc:kingbase8://{host}[:{port}]/[{database}][\\?{params}]")
|
||||||
|
.matcher("jdbc:kingbase8://localhost:54321/sample");
|
||||||
|
if (matcher6.matches()) {
|
||||||
|
System.out.println("kingbase8 host:" + matcher6.group("host"));
|
||||||
|
System.out.println("kingbase8 port:" + matcher6.group("port"));
|
||||||
|
System.out.println("kingbase8 database:" + matcher6.group("database"));
|
||||||
|
String params = matcher6.group("params");
|
||||||
|
if (null != params) {
|
||||||
|
String[] pairs = params.split("&");
|
||||||
|
for (String pair : pairs) {
|
||||||
|
System.out.println("mysql params:" + pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("error for kingbase8!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 8、达梦数据库
|
||||||
|
// jdbc:dm://localhost:5236/user?param=hello
|
||||||
|
final Matcher matcher7 = JDBCURL.getPattern("jdbc:dm://{host}:{port}[/{database}][\\?{params}]")
|
||||||
|
.matcher("jdbc:dm://localhost:5236");
|
||||||
|
if (matcher7.matches()) {
|
||||||
|
System.out.println("dm host:" + matcher7.group("host"));
|
||||||
|
System.out.println("dm port:" + matcher7.group("port"));
|
||||||
|
System.out.println("dm database:" + matcher7.group("database"));
|
||||||
|
String params = matcher7.group("params");
|
||||||
|
if (null != params) {
|
||||||
|
String[] pairs = params.split("&");
|
||||||
|
for (String pair : pairs) {
|
||||||
|
System.out.println("dm params:" + pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("error for dm!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9、DB2数据库
|
||||||
|
// jdbc:db2://localhost:50000/testdb:driverType=4;fullyMaterializeLobData=true;fullyMaterializeInputStreams=true;progressiveStreaming=2;progresssiveLocators=2;
|
||||||
|
final Matcher matcher8 = JDBCURL.getPattern("jdbc:db2://{host}:{port}/{database}[:{params}]")
|
||||||
|
.matcher("jdbc:db2://localhost:50000/testdb:driverType=4;fullyMaterializeLobData=true");
|
||||||
|
if (matcher8.matches()) {
|
||||||
|
System.out.println("db2 host:" + matcher8.group("host"));
|
||||||
|
System.out.println("db2 port:" + matcher8.group("port"));
|
||||||
|
System.out.println("db2 database:" + matcher8.group("database"));
|
||||||
|
String params = matcher8.group("params");
|
||||||
|
if (null != params) {
|
||||||
|
String[] pairs = params.split(";");
|
||||||
|
for (String pair : pairs) {
|
||||||
|
System.out.println("mysql params:" + pair);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
System.out.println("error for db2!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 9、SQLite数据库
|
||||||
|
// jdbc:sqlite:/tmp/phone.db
|
||||||
|
final Matcher matcher9 = JDBCURL.getPattern("jdbc:sqlite:{file}")
|
||||||
|
.matcher("jdbc:sqlite:D:\\Project\\Test\\phone.db");
|
||||||
|
if (matcher9.matches()) {
|
||||||
|
System.out.println("sqlite file:" + matcher9.group("file"));
|
||||||
|
} else {
|
||||||
|
System.out.println("error for sqlite!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -9,39 +9,44 @@
|
|||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
package com.gitee.dbswitch.dbchange;
|
package com.gitee.dbswitch.dbchange;
|
||||||
|
|
||||||
|
import com.gitee.dbswitch.dbchange.pojo.TaskParamBean;
|
||||||
|
import com.gitee.dbswitch.dbchange.util.JdbcTypesUtils;
|
||||||
|
import com.gitee.dbswitch.dbcommon.constant.Constants;
|
||||||
|
import com.gitee.dbswitch.dbcommon.database.DatabaseOperatorFactory;
|
||||||
|
import com.gitee.dbswitch.dbcommon.database.IDatabaseOperator;
|
||||||
|
import com.gitee.dbswitch.dbcommon.pojo.StatementResultSet;
|
||||||
|
import com.gitee.dbswitch.dbcommon.util.JdbcMetaDataUtils;
|
||||||
import java.sql.ResultSet;
|
import java.sql.ResultSet;
|
||||||
import java.sql.ResultSetMetaData;
|
import java.sql.ResultSetMetaData;
|
||||||
import java.sql.SQLException;
|
import java.sql.SQLException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.springframework.util.SerializationUtils;
|
|
||||||
import com.gitee.dbswitch.dbcommon.constant.Constants;
|
|
||||||
import com.gitee.dbswitch.dbcommon.database.DatabaseOperatorFactory;
|
|
||||||
import com.gitee.dbswitch.dbcommon.database.IDatabaseOperator;
|
|
||||||
import com.gitee.dbswitch.dbcommon.pojo.StatementResultSet;
|
|
||||||
import com.gitee.dbswitch.dbchange.pojo.TaskParamBean;
|
|
||||||
import com.gitee.dbswitch.dbchange.util.JdbcTypesUtils;
|
|
||||||
import com.gitee.dbswitch.dbcommon.util.JdbcMetaDataUtils;
|
|
||||||
import lombok.NonNull;
|
import lombok.NonNull;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import org.springframework.util.SerializationUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 数据变化量计算核心类
|
* 数据变化量计算核心类
|
||||||
*
|
*
|
||||||
* @author tang
|
* @author tang
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public final class ChangeCaculatorService implements IDatabaseChangeCaculator {
|
public final class ChangeCaculatorService implements IDatabaseChangeCaculator {
|
||||||
|
|
||||||
/** 是否记录不变化的记录 */
|
/**
|
||||||
|
* 是否记录不变化的记录
|
||||||
|
*/
|
||||||
private boolean recordIdentical;
|
private boolean recordIdentical;
|
||||||
|
|
||||||
/** 是否进行jdbc数据type检查 */
|
/**
|
||||||
|
* 是否进行jdbc数据type检查
|
||||||
|
*/
|
||||||
private boolean checkJdbcType;
|
private boolean checkJdbcType;
|
||||||
|
|
||||||
/** 批量读取数据的行数大小 */
|
/**
|
||||||
|
* 批量读取数据的行数大小
|
||||||
|
*/
|
||||||
private int queryFetchSize;
|
private int queryFetchSize;
|
||||||
|
|
||||||
public ChangeCaculatorService() {
|
public ChangeCaculatorService() {
|
||||||
@@ -82,7 +87,8 @@ public final class ChangeCaculatorService implements IDatabaseChangeCaculator {
|
|||||||
@Override
|
@Override
|
||||||
public void setFetchSize(int size) {
|
public void setFetchSize(int size) {
|
||||||
if (size < Constants.MINIMUM_FETCH_SIZE) {
|
if (size < Constants.MINIMUM_FETCH_SIZE) {
|
||||||
throw new IllegalArgumentException("设置的批量处理行数的大小fetchSize不得小于" + Constants.MINIMUM_FETCH_SIZE);
|
throw new IllegalArgumentException(
|
||||||
|
"设置的批量处理行数的大小fetchSize不得小于" + Constants.MINIMUM_FETCH_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.queryFetchSize = size;
|
this.queryFetchSize = size;
|
||||||
@@ -95,15 +101,20 @@ public final class ChangeCaculatorService implements IDatabaseChangeCaculator {
|
|||||||
log.debug("###### Begin execute calculate table CDC data now");
|
log.debug("###### Begin execute calculate table CDC data now");
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean useOwnFieldsColumns = (task.getFieldColumns() != null && !task.getFieldColumns().isEmpty());
|
boolean useOwnFieldsColumns = (task.getFieldColumns() != null && !task.getFieldColumns()
|
||||||
|
.isEmpty());
|
||||||
|
|
||||||
// 检查新旧两张表的主键字段与比较字段
|
// 检查新旧两张表的主键字段与比较字段
|
||||||
JdbcMetaDataUtils oldMd = new JdbcMetaDataUtils(task.getOldDataSource());
|
JdbcMetaDataUtils oldMd = new JdbcMetaDataUtils(task.getOldDataSource());
|
||||||
JdbcMetaDataUtils newMd = new JdbcMetaDataUtils(task.getNewDataSource());
|
JdbcMetaDataUtils newMd = new JdbcMetaDataUtils(task.getNewDataSource());
|
||||||
List<String> fieldsPrimaryKeyOld = oldMd.queryTablePrimaryKeys(task.getOldSchemaName(), task.getOldTableName());
|
List<String> fieldsPrimaryKeyOld = oldMd
|
||||||
List<String> fieldsAllColumnOld = oldMd.queryTableColumnName(task.getOldSchemaName(), task.getOldTableName());
|
.queryTablePrimaryKeys(task.getOldSchemaName(), task.getOldTableName());
|
||||||
List<String> fieldsPrimaryKeyNew = newMd.queryTablePrimaryKeys(task.getNewSchemaName(), task.getNewTableName());
|
List<String> fieldsAllColumnOld = oldMd
|
||||||
List<String> fieldsAllColumnNew = newMd.queryTableColumnName(task.getNewSchemaName(), task.getNewTableName());
|
.queryTableColumnName(task.getOldSchemaName(), task.getOldTableName());
|
||||||
|
List<String> fieldsPrimaryKeyNew = newMd
|
||||||
|
.queryTablePrimaryKeys(task.getNewSchemaName(), task.getNewTableName());
|
||||||
|
List<String> fieldsAllColumnNew = newMd
|
||||||
|
.queryTableColumnName(task.getNewSchemaName(), task.getNewTableName());
|
||||||
|
|
||||||
if (fieldsPrimaryKeyOld.isEmpty() || fieldsPrimaryKeyNew.isEmpty()) {
|
if (fieldsPrimaryKeyOld.isEmpty() || fieldsPrimaryKeyNew.isEmpty()) {
|
||||||
throw new RuntimeException("计算变化量的表中存在无主键的表");
|
throw new RuntimeException("计算变化量的表中存在无主键的表");
|
||||||
@@ -165,18 +176,22 @@ public final class ChangeCaculatorService implements IDatabaseChangeCaculator {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 提取新旧两表数据的结果集(按主键排序后的)
|
// 提取新旧两表数据的结果集(按主键排序后的)
|
||||||
IDatabaseOperator oldQuery = DatabaseOperatorFactory.createDatabaseOperator(task.getOldDataSource());
|
IDatabaseOperator oldQuery = DatabaseOperatorFactory
|
||||||
|
.createDatabaseOperator(task.getOldDataSource());
|
||||||
oldQuery.setFetchSize(this.queryFetchSize);
|
oldQuery.setFetchSize(this.queryFetchSize);
|
||||||
IDatabaseOperator newQuery = DatabaseOperatorFactory.createDatabaseOperator(task.getNewDataSource());
|
IDatabaseOperator newQuery = DatabaseOperatorFactory
|
||||||
|
.createDatabaseOperator(task.getNewDataSource());
|
||||||
newQuery.setFetchSize(this.queryFetchSize);
|
newQuery.setFetchSize(this.queryFetchSize);
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
if (log.isDebugEnabled()) {
|
||||||
log.debug("###### Query data from two table now");
|
log.debug("###### Query data from two table now");
|
||||||
}
|
}
|
||||||
|
|
||||||
rsold = oldQuery.queryTableData(task.getOldSchemaName(), task.getOldTableName(), queryFieldColumn,
|
rsold = oldQuery
|
||||||
|
.queryTableData(task.getOldSchemaName(), task.getOldTableName(), queryFieldColumn,
|
||||||
fieldsPrimaryKeyOld);
|
fieldsPrimaryKeyOld);
|
||||||
rsnew = newQuery.queryTableData(task.getNewSchemaName(), task.getNewTableName(), queryFieldColumn,
|
rsnew = newQuery
|
||||||
|
.queryTableData(task.getNewSchemaName(), task.getNewTableName(), queryFieldColumn,
|
||||||
fieldsPrimaryKeyNew);
|
fieldsPrimaryKeyNew);
|
||||||
ResultSetMetaData metaData = rsold.getResultset().getMetaData();
|
ResultSetMetaData metaData = rsold.getResultset().getMetaData();
|
||||||
|
|
||||||
@@ -202,7 +217,8 @@ public final class ChangeCaculatorService implements IDatabaseChangeCaculator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!key1.equals(key2)) {
|
if (!key1.equals(key2)) {
|
||||||
throw new RuntimeException(String.format("字段名称 [Index=%d] 不同,因 %s!=%s !", k, key1, key2));
|
throw new RuntimeException(
|
||||||
|
String.format("字段名称 [Index=%d] 不同,因 %s!=%s !", k, key1, key2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (checkJdbcType) {
|
if (checkJdbcType) {
|
||||||
@@ -349,7 +365,8 @@ public final class ChangeCaculatorService implements IDatabaseChangeCaculator {
|
|||||||
* @return 比较的结果:0,-1,1
|
* @return 比较的结果:0,-1,1
|
||||||
* @throws SQLException
|
* @throws SQLException
|
||||||
*/
|
*/
|
||||||
private int compare(Object[] obj1, Object[] obj2, int[] fieldnrs, ResultSetMetaData metaData) throws SQLException {
|
private int compare(Object[] obj1, Object[] obj2, int[] fieldnrs, ResultSetMetaData metaData)
|
||||||
|
throws SQLException {
|
||||||
if (obj1.length != obj2.length) {
|
if (obj1.length != obj2.length) {
|
||||||
throw new RuntimeException("Invalid compare object list !");
|
throw new RuntimeException("Invalid compare object list !");
|
||||||
}
|
}
|
||||||
@@ -401,11 +418,13 @@ public final class ChangeCaculatorService implements IDatabaseChangeCaculator {
|
|||||||
String s1 = String.valueOf(o1);
|
String s1 = String.valueOf(o1);
|
||||||
String s2 = String.valueOf(o2);
|
String s2 = String.valueOf(o2);
|
||||||
return s1.compareTo(s2);
|
return s1.compareTo(s2);
|
||||||
} else if (JdbcTypesUtils.isNumeric(type) && o1 instanceof java.lang.Number && o2 instanceof java.lang.Number) {
|
} else if (JdbcTypesUtils.isNumeric(type) && o1 instanceof java.lang.Number
|
||||||
|
&& o2 instanceof java.lang.Number) {
|
||||||
java.lang.Number s1 = (java.lang.Number) o1;
|
java.lang.Number s1 = (java.lang.Number) o1;
|
||||||
java.lang.Number s2 = (java.lang.Number) o2;
|
java.lang.Number s2 = (java.lang.Number) o2;
|
||||||
return Double.compare(s1.doubleValue(), s2.doubleValue());
|
return Double.compare(s1.doubleValue(), s2.doubleValue());
|
||||||
} else if (JdbcTypesUtils.isInteger(type) && o1 instanceof java.lang.Number && o2 instanceof java.lang.Number) {
|
} else if (JdbcTypesUtils.isInteger(type) && o1 instanceof java.lang.Number
|
||||||
|
&& o2 instanceof java.lang.Number) {
|
||||||
java.lang.Number s1 = (java.lang.Number) o1;
|
java.lang.Number s1 = (java.lang.Number) o1;
|
||||||
java.lang.Number s2 = (java.lang.Number) o2;
|
java.lang.Number s2 = (java.lang.Number) o2;
|
||||||
return Long.compare(s1.longValue(), s2.longValue());
|
return Long.compare(s1.longValue(), s2.longValue());
|
||||||
@@ -428,7 +447,12 @@ public final class ChangeCaculatorService implements IDatabaseChangeCaculator {
|
|||||||
return s1.compareTo(s2);
|
return s1.compareTo(s2);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
try {
|
||||||
return compareTo(SerializationUtils.serialize(o1), SerializationUtils.serialize(o2));
|
return compareTo(SerializationUtils.serialize(o1), SerializationUtils.serialize(o2));
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.warn("CDC compare field value failed, return 0 instead,{}", e.getMessage());
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,7 +15,6 @@ import com.gitee.dbswitch.dbchange.pojo.TaskParamBean;
|
|||||||
* 变化量计算器接口定义
|
* 变化量计算器接口定义
|
||||||
*
|
*
|
||||||
* @author tang
|
* @author tang
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface IDatabaseChangeCaculator {
|
public interface IDatabaseChangeCaculator {
|
||||||
|
|
||||||
@@ -24,42 +23,42 @@ public interface IDatabaseChangeCaculator {
|
|||||||
*
|
*
|
||||||
* @return 是否记录无变化的数据
|
* @return 是否记录无变化的数据
|
||||||
*/
|
*/
|
||||||
public boolean isRecordIdentical();
|
boolean isRecordIdentical();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置是否记录无变化的数据
|
* 设置是否记录无变化的数据
|
||||||
*
|
*
|
||||||
* @param recordOrNot 是否记录无变化的数据
|
* @param recordOrNot 是否记录无变化的数据
|
||||||
*/
|
*/
|
||||||
public void setRecordIdentical(boolean recordOrNot);
|
void setRecordIdentical(boolean recordOrNot);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 是否进行Jdbc的数据类型检查
|
* 是否进行Jdbc的数据类型检查
|
||||||
*
|
*
|
||||||
* @return 是否进行检查
|
* @return 是否进行检查
|
||||||
*/
|
*/
|
||||||
public boolean isCheckJdbcType();
|
boolean isCheckJdbcType();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置是否进行Jdbc的数据类型检查
|
* 设置是否进行Jdbc的数据类型检查
|
||||||
*
|
*
|
||||||
* @param checkOrNot 是否进行检查
|
* @param checkOrNot 是否进行检查
|
||||||
*/
|
*/
|
||||||
public void setCheckJdbcType(boolean checkOrNot);
|
void setCheckJdbcType(boolean checkOrNot);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取JDBC驱动批量读取数据的行数大小
|
* 获取JDBC驱动批量读取数据的行数大小
|
||||||
*
|
*
|
||||||
* @return 批量行数大小
|
* @return 批量行数大小
|
||||||
*/
|
*/
|
||||||
public int getFetchSize();
|
int getFetchSize();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置JDBC驱动批量读取数据的行数大小
|
* 设置JDBC驱动批量读取数据的行数大小
|
||||||
*
|
*
|
||||||
* @param size 批量行数大小
|
* @param size 批量行数大小
|
||||||
*/
|
*/
|
||||||
public void setFetchSize(int size);
|
void setFetchSize(int size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 执行变化量计算任务
|
* 执行变化量计算任务
|
||||||
@@ -67,5 +66,5 @@ public interface IDatabaseChangeCaculator {
|
|||||||
* @param task 任务描述实体对象
|
* @param task 任务描述实体对象
|
||||||
* @param handler 计算结果回调处理器
|
* @param handler 计算结果回调处理器
|
||||||
*/
|
*/
|
||||||
public void executeCalculate(TaskParamBean task, IDatabaseRowHandler handler);
|
void executeCalculate(TaskParamBean task, IDatabaseRowHandler handler);
|
||||||
}
|
}
|
||||||
|
@@ -15,7 +15,6 @@ import java.util.List;
|
|||||||
* 计算结果行记录处理器
|
* 计算结果行记录处理器
|
||||||
*
|
*
|
||||||
* @author tang
|
* @author tang
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface IDatabaseRowHandler {
|
public interface IDatabaseRowHandler {
|
||||||
|
|
||||||
@@ -26,12 +25,12 @@ public interface IDatabaseRowHandler {
|
|||||||
* @param record 一条数据记实录
|
* @param record 一条数据记实录
|
||||||
* @param flag 数据变化状态
|
* @param flag 数据变化状态
|
||||||
*/
|
*/
|
||||||
public void handle(List<String> fields, Object[] record, RecordChangeTypeEnum flag);
|
void handle(List<String> fields, Object[] record, RecordChangeTypeEnum flag);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 计算结束通知
|
* 计算结束通知
|
||||||
*
|
*
|
||||||
* @param fields 字段名称列表,该列表只读
|
* @param fields 字段名称列表,该列表只读
|
||||||
*/
|
*/
|
||||||
public void destroy(List<String> fields);
|
void destroy(List<String> fields);
|
||||||
}
|
}
|
||||||
|
@@ -13,7 +13,6 @@ package com.gitee.dbswitch.dbchange;
|
|||||||
* 记录变化状态枚举类
|
* 记录变化状态枚举类
|
||||||
*
|
*
|
||||||
* @author tang
|
* @author tang
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public enum RecordChangeTypeEnum {
|
public enum RecordChangeTypeEnum {
|
||||||
/**
|
/**
|
||||||
@@ -34,13 +33,16 @@ public enum RecordChangeTypeEnum {
|
|||||||
/**
|
/**
|
||||||
* 删除标识
|
* 删除标识
|
||||||
*/
|
*/
|
||||||
VALUE_DELETED(3, "delete")
|
VALUE_DELETED(3, "delete");
|
||||||
;
|
|
||||||
|
|
||||||
/** index */
|
/**
|
||||||
|
* index
|
||||||
|
*/
|
||||||
private Integer index;
|
private Integer index;
|
||||||
|
|
||||||
/** 状态标记 */
|
/**
|
||||||
|
* 状态标记
|
||||||
|
*/
|
||||||
private String status;
|
private String status;
|
||||||
|
|
||||||
RecordChangeTypeEnum(int idx, String flag) {
|
RecordChangeTypeEnum(int idx, String flag) {
|
||||||
|
@@ -21,12 +21,12 @@ import lombok.AllArgsConstructor;
|
|||||||
* 任务参数实体类定义
|
* 任务参数实体类定义
|
||||||
*
|
*
|
||||||
* @author tang
|
* @author tang
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@Builder
|
@Builder
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
public class TaskParamBean {
|
public class TaskParamBean {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 老表的数据源
|
* 老表的数据源
|
||||||
*/
|
*/
|
||||||
|
@@ -18,7 +18,6 @@ import java.util.Map;
|
|||||||
* JDBC的数据类型相关工具类
|
* JDBC的数据类型相关工具类
|
||||||
*
|
*
|
||||||
* @author tang
|
* @author tang
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public final class JdbcTypesUtils {
|
public final class JdbcTypesUtils {
|
||||||
|
|
||||||
@@ -64,7 +63,8 @@ public final class JdbcTypesUtils {
|
|||||||
*/
|
*/
|
||||||
public static boolean isInteger(int sqlType) {
|
public static boolean isInteger(int sqlType) {
|
||||||
// 5
|
// 5
|
||||||
return (Types.BIT == sqlType || Types.BIGINT == sqlType || Types.INTEGER == sqlType || Types.SMALLINT == sqlType
|
return (Types.BIT == sqlType || Types.BIGINT == sqlType || Types.INTEGER == sqlType
|
||||||
|
|| Types.SMALLINT == sqlType
|
||||||
|| Types.TINYINT == sqlType);
|
|| Types.TINYINT == sqlType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +77,8 @@ public final class JdbcTypesUtils {
|
|||||||
public static boolean isString(int sqlType) {
|
public static boolean isString(int sqlType) {
|
||||||
// 10
|
// 10
|
||||||
return (Types.CHAR == sqlType || Types.NCHAR == sqlType || Types.VARCHAR == sqlType
|
return (Types.CHAR == sqlType || Types.NCHAR == sqlType || Types.VARCHAR == sqlType
|
||||||
|| Types.LONGVARCHAR == sqlType || Types.NVARCHAR == sqlType || Types.LONGNVARCHAR == sqlType
|
|| Types.LONGVARCHAR == sqlType || Types.NVARCHAR == sqlType
|
||||||
|
|| Types.LONGNVARCHAR == sqlType
|
||||||
|| Types.CLOB == sqlType || Types.NCLOB == sqlType || Types.SQLXML == sqlType
|
|| Types.CLOB == sqlType || Types.NCLOB == sqlType || Types.SQLXML == sqlType
|
||||||
|| Types.ROWID == sqlType);
|
|| Types.ROWID == sqlType);
|
||||||
}
|
}
|
||||||
@@ -118,7 +119,7 @@ public final class JdbcTypesUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isTextable(int sqlType) {
|
public static boolean isTextable(int sqlType) {
|
||||||
return isNumeric(sqlType) || isString(sqlType) || isDateTime(sqlType) || isBoolean(sqlType) ;
|
return isNumeric(sqlType) || isString(sqlType) || isDateTime(sqlType) || isBoolean(sqlType);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 其他类型如下:9个
|
// 其他类型如下:9个
|
||||||
|
Reference in New Issue
Block a user