!86 version for 1.6.6

* version for 1.6.6
This commit is contained in:
inrgihc
2022-03-16 14:56:26 +00:00
parent 3268385b2a
commit 0312a4b1a4
134 changed files with 3680 additions and 1956 deletions

View File

@@ -5,7 +5,7 @@
<parent>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-parent</artifactId>
<version>1.6.5</version>
<version>1.6.6</version>
</parent>
<artifactId>dbswitch-dbchange</artifactId>
@@ -18,6 +18,12 @@
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.gitee.dbswitch</groupId>
<artifactId>dbswitch-core</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>

View File

@@ -9,20 +9,24 @@
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.dbchange;
import com.gitee.dbswitch.core.service.IMetaDataByDatasourceService;
import com.gitee.dbswitch.core.service.impl.MetaDataByDataSourceServiceImpl;
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.domain.StatementResultSet;
import com.gitee.dbswitch.dbcommon.util.JdbcMetaDataUtils;
import com.gitee.dbswitch.dbcommon.util.JdbcTypesUtils;
import com.gitee.dbswitch.common.util.JdbcTypesUtils;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.springframework.util.SerializationUtils;
/**
@@ -93,20 +97,31 @@ public final class ChangeCalculatorService implements IDatabaseChangeCaculator {
this.queryFetchSize = size;
}
/**
* 变化量计算函数
* <p>
* 说明 old 后缀的为目标段; new 后缀的为来源段;
* <p>
* 数据由 new 向 old 方向 同步。
*
* @param task 任务描述实体对象
* @param handler 计算结果回调处理器
*/
@Override
public void executeCalculate(@NonNull TaskParamEntity task,
@NonNull IDatabaseRowHandler handler) {
if (log.isDebugEnabled()) {
log.debug("###### Begin execute calculate table CDC data now");
}
boolean useOwnFieldsColumns = (task.getFieldColumns() != null && !task.getFieldColumns()
.isEmpty());
Map<String, String> columnsMap = task.getColumnsMap();
boolean useOwnFieldsColumns = !CollectionUtils.isEmpty(task.getFieldColumns());
// 检查新旧两张表的主键字段与比较字段
JdbcMetaDataUtils oldMd = new JdbcMetaDataUtils(task.getOldDataSource());
JdbcMetaDataUtils newMd = new JdbcMetaDataUtils(task.getNewDataSource());
IMetaDataByDatasourceService
oldMd = new MetaDataByDataSourceServiceImpl(task.getOldDataSource());
IMetaDataByDatasourceService
newMd = new MetaDataByDataSourceServiceImpl(task.getNewDataSource());
List<String> fieldsPrimaryKeyOld = oldMd
.queryTablePrimaryKeys(task.getOldSchemaName(), task.getOldTableName());
List<String> fieldsAllColumnOld = oldMd
@@ -115,42 +130,45 @@ public final class ChangeCalculatorService implements IDatabaseChangeCaculator {
.queryTablePrimaryKeys(task.getNewSchemaName(), task.getNewTableName());
List<String> fieldsAllColumnNew = newMd
.queryTableColumnName(task.getNewSchemaName(), task.getNewTableName());
List<String> fieldsMappedPrimaryKeyNew = fieldsPrimaryKeyNew.stream()
.map(s -> columnsMap.getOrDefault(s, s))
.collect(Collectors.toList());
List<String> fieldsMappedAllColumnNew = fieldsAllColumnNew.stream()
.map(s -> columnsMap.getOrDefault(s, s))
.collect(Collectors.toList());
if (fieldsPrimaryKeyOld.isEmpty() || fieldsPrimaryKeyNew.isEmpty()) {
throw new RuntimeException("计算变化量的表中存在无主键的表");
}
boolean same = (fieldsPrimaryKeyOld.containsAll(fieldsPrimaryKeyNew)
&& fieldsPrimaryKeyNew.containsAll(fieldsPrimaryKeyOld));
if (!same) {
throw new RuntimeException("两个表的主键不相同");
if (!isListEqual(fieldsPrimaryKeyOld, fieldsMappedPrimaryKeyNew)) {
throw new RuntimeException("两个表的主键映射关系不匹配");
}
if (useOwnFieldsColumns) {
if (!fieldsAllColumnOld.containsAll(task.getFieldColumns())
|| !fieldsAllColumnNew.containsAll(task.getFieldColumns())) {
// 如果自己配置了字段列表,判断子集关系
List<String> mappedFieldColumns = task.getFieldColumns().stream()
.map(s -> columnsMap.getOrDefault(s, s))
.collect(Collectors.toList());
if (!fieldsAllColumnNew.containsAll(task.getFieldColumns())
|| !fieldsAllColumnOld.containsAll(mappedFieldColumns)) {
throw new RuntimeException("指定的字段列不完全在两个表中存在");
}
} else {
same = (fieldsAllColumnOld.containsAll(fieldsPrimaryKeyNew)
&& fieldsAllColumnNew.containsAll(fieldsAllColumnOld));
if (!same) {
throw new RuntimeException("两个表的字段不相同");
}
}
if (useOwnFieldsColumns) {
// 如果自己配置了字段列表
same = (task.getFieldColumns().containsAll(fieldsPrimaryKeyNew)
&& task.getFieldColumns().containsAll(fieldsPrimaryKeyOld));
boolean same = (mappedFieldColumns.containsAll(fieldsPrimaryKeyOld)
&& task.getFieldColumns().containsAll(fieldsPrimaryKeyNew));
if (!same) {
throw new RuntimeException("提供的比较字段中未包含主键");
}
same = (fieldsAllColumnOld.containsAll(task.getFieldColumns())
same = (fieldsAllColumnOld.containsAll(mappedFieldColumns)
&& fieldsAllColumnNew.containsAll(task.getFieldColumns()));
if (!same) {
throw new RuntimeException("提供的比较字段中存在表中不存在的字段");
throw new RuntimeException("提供的比较字段中存在表中不存在(映射关系对不上)的字段");
}
} else {
boolean same = (fieldsMappedAllColumnNew.containsAll(fieldsPrimaryKeyOld)
&& fieldsAllColumnOld.containsAll(fieldsMappedAllColumnNew));
if (!same) {
throw new RuntimeException("两个表的字段映射关系不匹配");
}
}
@@ -159,17 +177,21 @@ public final class ChangeCalculatorService implements IDatabaseChangeCaculator {
if (useOwnFieldsColumns) {
fieldsOfCompareValue.addAll(task.getFieldColumns());
} else {
fieldsOfCompareValue.addAll(fieldsAllColumnOld);
fieldsOfCompareValue.addAll(fieldsAllColumnNew);
}
fieldsOfCompareValue.removeAll(fieldsPrimaryKeyOld);
fieldsOfCompareValue.removeAll(fieldsPrimaryKeyNew);
// 构造查询列字段
List<String> queryFieldColumn;
List<String> mappedQueryFieldColumn;
if (useOwnFieldsColumns) {
queryFieldColumn = task.getFieldColumns();
} else {
queryFieldColumn = fieldsAllColumnOld;
}
mappedQueryFieldColumn = queryFieldColumn.stream()
.map(s -> columnsMap.getOrDefault(s, s))
.collect(Collectors.toList());
StatementResultSet rsold = null;
StatementResultSet rsnew = null;
@@ -188,12 +210,12 @@ public final class ChangeCalculatorService implements IDatabaseChangeCaculator {
}
rsold = oldQuery
.queryTableData(task.getOldSchemaName(), task.getOldTableName(), queryFieldColumn,
fieldsPrimaryKeyOld);
.queryTableData(task.getOldSchemaName(), task.getOldTableName(),
mappedQueryFieldColumn, fieldsMappedPrimaryKeyNew);
rsnew = newQuery
.queryTableData(task.getNewSchemaName(), task.getNewTableName(), queryFieldColumn,
fieldsPrimaryKeyNew);
ResultSetMetaData metaData = rsold.getResultset().getMetaData();
.queryTableData(task.getNewSchemaName(), task.getNewTableName(),
queryFieldColumn, fieldsPrimaryKeyNew);
ResultSetMetaData metaData = rsnew.getResultset().getMetaData();
if (log.isDebugEnabled()) {
log.debug("###### Check data validate now");
@@ -206,26 +228,22 @@ public final class ChangeCalculatorService implements IDatabaseChangeCaculator {
throw new RuntimeException(String.format("两个表的字段总个数不相等,即:%d!=%d", oldcnt, newcnt));
} else {
for (int k = 1; k < metaData.getColumnCount(); ++k) {
String key1 = rsold.getResultset().getMetaData().getColumnLabel(k);
String key1 = rsnew.getResultset().getMetaData().getColumnLabel(k);
if (null == key1) {
key1 = rsold.getResultset().getMetaData().getColumnName(k);
key1 = rsnew.getResultset().getMetaData().getColumnName(k);
}
String key2 = rsnew.getResultset().getMetaData().getColumnLabel(k);
String key2 = rsold.getResultset().getMetaData().getColumnLabel(k);
if (null == key2) {
key2 = rsnew.getResultset().getMetaData().getColumnName(k);
}
if (!key1.equals(key2)) {
throw new RuntimeException(
String.format("字段名称 [Index=%d] 不同,因 %s!=%s !", k, key1, key2));
key2 = rsold.getResultset().getMetaData().getColumnName(k);
}
if (checkJdbcType) {
int type1 = rsold.getResultset().getMetaData().getColumnType(k);
int type2 = rsnew.getResultset().getMetaData().getColumnType(k);
if (type1 != type2) {
throw new RuntimeException(String.format("字段 [name=%s] 的数据类型不同,因 %s!=%s !", key1,
throw new RuntimeException(String.format("字段 [name=%s -> %s] 的数据类型不同,因 %s!=%s !",
key1, key2,
JdbcTypesUtils.resolveTypeName(type1), JdbcTypesUtils.resolveTypeName(type2)));
}
}
@@ -234,9 +252,9 @@ public final class ChangeCalculatorService implements IDatabaseChangeCaculator {
}
// 计算主键字段序列在结果集中的索引号
int[] keyNumbers = new int[fieldsPrimaryKeyOld.size()];
int[] keyNumbers = new int[fieldsPrimaryKeyNew.size()];
for (int i = 0; i < keyNumbers.length; ++i) {
String fn = fieldsPrimaryKeyOld.get(i);
String fn = fieldsPrimaryKeyNew.get(i);
keyNumbers[i] = getIndexOfField(fn, metaData);
}
@@ -254,7 +272,7 @@ public final class ChangeCalculatorService implements IDatabaseChangeCaculator {
if (null == key) {
key = metaData.getColumnName(k);
}
targetColumns.add(key);
targetColumns.add(columnsMap.getOrDefault(key, key));
}
if (log.isDebugEnabled()) {
@@ -332,6 +350,10 @@ public final class ChangeCalculatorService implements IDatabaseChangeCaculator {
}
private boolean isListEqual(List<String> left, List<String> right) {
return left.containsAll(right) && right.containsAll(left);
}
/**
* 获取字段的索引号
*

View File

@@ -9,6 +9,8 @@
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.dbchange;
import java.util.Map;
/**
* 变化量计算器接口定义
*

View File

@@ -9,13 +9,14 @@
/////////////////////////////////////////////////////////////
package com.gitee.dbswitch.dbchange;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NonNull;
import org.springframework.lang.Nullable;
/**
* 任务参数实体类定义
@@ -31,7 +32,7 @@ public class TaskParamEntity {
* 老表的数据源
*/
@NonNull
DataSource oldDataSource;
private DataSource oldDataSource;
/**
* 老表的schema名
@@ -49,7 +50,7 @@ public class TaskParamEntity {
* 新表的数据源
*/
@NonNull
DataSource newDataSource;
private DataSource newDataSource;
/**
* 新表的schema名
@@ -66,6 +67,12 @@ public class TaskParamEntity {
/**
* 字段列
*/
@Nullable
private List<String> fieldColumns;
/**
* 字段名映射关系
*/
@NonNull
@Builder.Default
private Map<String, String> columnsMap = Collections.EMPTY_MAP;
}