From 044f97d5c38d4bdfff0d36c7dc311a0681743664 Mon Sep 17 00:00:00 2001 From: inrgihc Date: Tue, 1 Jun 2021 23:35:00 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BB=A3=E7=A0=81=E4=BC=98=E5=8C=96=E4=B8=8E?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=8B=BC=E5=86=99=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- LICENSE | 2 +- build.sh | 3 +- .../common/constant/DatabaseTypeEnum.java | 2 +- .../dbswitch/common/util/CommonUtils.java | 108 +- .../gitee/dbswitch/core/constant/Const.java | 3 +- .../dbswitch/core/constant/DBTableType.java | 2 +- .../core/database/AbstractDatabase.java | 2 +- .../core/database/DatabaseFactory.java | 2 +- .../core/database/IDatabaseInterface.java | 2 +- .../core/database/impl/DatabaseDB2Impl.java | 5 +- .../core/database/impl/DatabaseDmImpl.java | 2 +- .../database/impl/DatabaseGreenplumImpl.java | 6 +- .../database/impl/DatabaseKingbaseImpl.java | 5 +- .../database/impl/DatabaseMariaDBImpl.java | 2 +- .../core/database/impl/DatabaseMysqlImpl.java | 9 +- .../database/impl/DatabaseOracleImpl.java | 8 +- .../database/impl/DatabasePostgresImpl.java | 7 +- .../impl/DatabaseSqlserver2000Impl.java | 2 +- .../database/impl/DatabaseSqlserverImpl.java | 8 +- .../core/model/ColumnDescription.java | 2 +- .../dbswitch/core/model/ColumnMetaData.java | 8 +- .../core/model/DatabaseDescription.java | 4 +- .../dbswitch/core/model/TableDescription.java | 1 + .../dbswitch/core/util/GenerateSqlUtils.java | 7 +- dbswitch-data/pom.xml | 6 + .../dbswitch/data/DataSyncApplication.java | 2 +- .../data/config/DbswichProperties.java | 2 +- .../data/config/PropertiesConfig.java | 2 +- .../dbswitch/data/service/MainService.java | 32 +- .../dbswitch/data/util/JdbcTemplateUtils.java | 2 +- .../dbchange/ChangeCaculatorService.java | 2 +- .../dbchange/IDatabaseChangeCaculator.java | 2 +- .../dbchange/IDatabaseRowHandler.java | 2 +- .../dbchange/RecordChangeTypeEnum.java | 2 +- .../dbswitch/dbchange/pojo/TaskParamBean.java | 2 +- .../dbchange/util/JdbcTypesUtils.java | 2 +- .../dbswitch/dbcommon/constant/Constants.java | 2 +- .../database/AbstractDatabaseOperator.java | 145 +- .../database/DatabaseOperatorFactory.java | 68 +- .../dbcommon/database/IDatabaseOperator.java | 2 +- .../database/impl/DB2DatabaseOperator.java | 2 +- .../database/impl/DmDatabaseOperator.java | 15 + .../impl/GreenplumDatabaseOperator.java | 2 +- .../impl/KingbaseDatabaseOperator.java | 15 + .../database/impl/MysqlDatabaseOperator.java | 2 +- .../database/impl/OracleDatabaseOperator.java | 2 +- .../impl/PostgreSqlDatabaseOperator.java | 2 +- .../impl/SqlServerDatabaseOperator.java | 2 +- .../dbcommon/pojo/StatementResultSet.java | 2 +- .../dbcommon/util/DatabaseAwareUtils.java | 2 +- .../dbcommon/util/JdbcMetaDataUtils.java | 8 +- .../dbsynch/AbstractDatabaseSynchronize.java | 470 ++- .../dbsynch/DatabaseSynchronizeFactory.java | 68 +- .../dbsynch/IDatabaseSynchronize.java | 2 +- .../dbsynch/db2/DB2DatabaseSynchImpl.java | 83 +- .../dbsynch/dm/DmDatabaseSynchImpl.java | 8 +- .../kingbase/KingbaseDatabaseSynchImpl.java | 9 +- .../mssql/SqlServerDatabaseSynchImpl.java | 83 +- .../dbsynch/mysql/MySqlDatabaseSynchImpl.java | 83 +- .../oracle/OracleDatabaseSynchImpl.java | 83 +- .../pgsql/GreenplumDatabaseSynchImpl.java | 4 +- .../pgsql/PostgresqlDatabaseSynchImpl.java | 83 +- .../dbwriter/AbstractDatabaseWriter.java | 2 +- .../dbwriter/DatabaseWriterFactory.java | 46 +- .../dbswitch/dbwriter/IDatabaseWriter.java | 2 +- .../dbswitch/dbwriter/db2/DB2WriterImpl.java | 12 +- .../dbswitch/dbwriter/dm/DmWriterImpl.java | 8 +- .../gpdb/GreenplumCopyWriterImpl.java | 2558 ++++++++--------- .../gpdb/GreenplumInsertWriterImpl.java | 86 +- .../kingbase/KingbaseCopyWriterImpl.java | 8 +- .../kingbase/KingbaseInsertWriterImpl.java | 8 +- .../dbwriter/mssql/SqlServerWriterImpl.java | 172 +- .../dbwriter/mysql/MySqlWriterImpl.java | 85 +- .../dbwriter/oracle/OracleWriterImpl.java | 72 +- .../sql/calcite/TheMssqlSqlDialect.java | 2 +- .../sql/calcite/TheMysqlSqlDialect.java | 2 +- .../sql/calcite/TheOracleSqlDialect.java | 2 +- .../sql/calcite/ThePostgresqlSqlDialect.java | 2 +- .../dbswitch/sql/calcite/TheSqlOrderBy.java | 2 +- .../sql/calcite/TheSqlRowOperator.java | 2 +- .../gitee/dbswitch/sql/constant/Const.java | 2 +- .../sql/ddl/AbstractDatabaseDialect.java | 2 +- .../sql/ddl/AbstractSqlDdlOperator.java | 2 +- .../sql/ddl/pojo/ColumnDefinition.java | 2 +- .../sql/ddl/pojo/TableDefinition.java | 2 +- .../sql/ddl/sql/DdlSqlAlterTable.java | 2 +- .../sql/ddl/sql/DdlSqlCreateTable.java | 2 +- .../dbswitch/sql/ddl/sql/DdlSqlDropTable.java | 2 +- .../sql/ddl/sql/DdlSqlTruncateTable.java | 2 +- .../ddl/sql/impl/GreenplumDialectImpl.java | 2 +- .../sql/ddl/sql/impl/MySqlDialectImpl.java | 2 +- .../sql/ddl/sql/impl/OracleDialectImpl.java | 2 +- .../sql/ddl/sql/impl/PostgresDialectImpl.java | 2 +- .../sql/ddl/type/GreenplumDataTypeEnum.java | 2 +- .../sql/ddl/type/MySqlDataTypeEnum.java | 2 +- .../sql/ddl/type/OracleDataTypeEnum.java | 2 +- .../sql/ddl/type/PostgresDataTypeEnum.java | 2 +- .../sql/service/ISqlConvertService.java | 2 +- .../sql/service/ISqlGeneratorService.java | 2 +- .../impl/CalciteSqlConvertServiceImpl.java | 2 +- .../impl/MyselfSqlGeneratorServiceImpl.java | 18 +- .../webapi/WebServiceApplication.java | 7 +- .../dbswitch/webapi/aspect/WebLogAspect.java | 2 +- .../webapi/config/ActuatorSecurityConfig.java | 2 +- .../config/AdapterBeanConfiguration.java | 2 +- .../dbswitch/webapi/config/SwaggerConfig.java | 2 +- .../webapi/controller/ConvertController.java | 2 +- .../controller/ExceptionController.java | 2 +- .../controller/GeneratorController.java | 2 +- .../controller/StructureController.java | 2 +- .../dbswitch/webapi/model/ResponseResult.java | 3 +- .../webapi/SwitchApplicationTests.java | 2 +- pom.xml | 14 +- 113 files changed, 2338 insertions(+), 2340 deletions(-) diff --git a/LICENSE b/LICENSE index 28eca872..b6265e98 100644 --- a/LICENSE +++ b/LICENSE @@ -1,5 +1,5 @@ // dbswitch - 一个Java语言编写的异构数据库迁移工具 -// Copyright (c) 2019, tang. All rights reserved. +// Copyright (c) 2020, tang(inrgihc@126.com). All rights reserved. // Use of this source code is governed by a BSD-style license // https://gitee.com/inrgihc/dbswitch // diff --git a/build.sh b/build.sh index 2ed0dd13..40911f0d 100644 --- a/build.sh +++ b/build.sh @@ -1,4 +1,3 @@ #!/bin/sh -mvn clean -f pom.xml -mvn package -f pom.xml -Dmaven.test.skip=true +mvn clean package -Dmaven.test.skip=true diff --git a/dbswitch-common/src/main/java/com/gitee/dbswitch/common/constant/DatabaseTypeEnum.java b/dbswitch-common/src/main/java/com/gitee/dbswitch/common/constant/DatabaseTypeEnum.java index 5f6852e7..ec1469ca 100644 --- a/dbswitch-common/src/main/java/com/gitee/dbswitch/common/constant/DatabaseTypeEnum.java +++ b/dbswitch-common/src/main/java/com/gitee/dbswitch/common/constant/DatabaseTypeEnum.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.common.constant; diff --git a/dbswitch-common/src/main/java/com/gitee/dbswitch/common/util/CommonUtils.java b/dbswitch-common/src/main/java/com/gitee/dbswitch/common/util/CommonUtils.java index e2b03ece..4a1117cc 100644 --- a/dbswitch-common/src/main/java/com/gitee/dbswitch/common/util/CommonUtils.java +++ b/dbswitch-common/src/main/java/com/gitee/dbswitch/common/util/CommonUtils.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.common.util; @@ -14,63 +14,71 @@ import com.gitee.dbswitch.common.constant.DatabaseTypeEnum; /** * 普通工具类 - * - * @author tang * + * @author tang */ public final class CommonUtils { - private CommonUtils() { + private CommonUtils() { + } - } + /** + * 根据数据库类型获取表的全名:schema.table + * + * @param dbType 数据库类型 + * @param schema schema名 + * @param table table名 + * @return 表的全名字符串 + */ + public static String getTableFullNameByDatabase(DatabaseTypeEnum dbType, String schema, String table) { + if (dbType == DatabaseTypeEnum.MYSQL || dbType == DatabaseTypeEnum.MARIADB) { + return String.format("`%s`.`%s`", schema, table); + } else if (dbType == DatabaseTypeEnum.SQLSERVER || dbType == DatabaseTypeEnum.SQLSERVER2000) { + return String.format("[%s].[%s]", schema, table); + } else { + return String.format("\"%s\".\"%s\"", schema, table); + } + } - public static String getTableFullNameByDatabase(DatabaseTypeEnum dbtype, String schemaName, String tableName) { - if (dbtype == DatabaseTypeEnum.MYSQL) { - return String.format("`%s`.`%s`", schemaName, tableName); - } else if (dbtype == DatabaseTypeEnum.SQLSERVER) { - return String.format("[%s].[%s]", schemaName, tableName); - } else { - return String.format("\"%s\".\"%s\"", schemaName, tableName); - } - } + /** + * 拼接SELECT查询指定字段的SQL语句 + * + * @param dbType 数据库类型 + * @param schema schema名 + * @param table table名 + * @param columns 列名列表 + * @return SQL语句字符串 + */ + public static String getSelectColumnsSQL(DatabaseTypeEnum dbType, String schema, String table, List columns) { + StringBuilder sb = new StringBuilder(); + sb.append(" SELECT "); + for (int i = 0; i < columns.size(); ++i) { + String field = columns.get(i); + String quoteField = quoteString(dbType, field); + sb.append(quoteField); - public static String getSelectColumnsSQL(DatabaseTypeEnum dbtype, String schema, String table, List columns) { - StringBuilder sb = new StringBuilder(); - sb.append(" SELECT "); - for (int i = 0; i < columns.size(); ++i) { - String field = columns.get(i); - String quoteField = quoteString(dbtype, field); - sb.append(quoteField); + if (i < columns.size() - 1) { + sb.append(","); + } + } + sb.append(" FROM "); + if (null != schema && !schema.isEmpty()) { + sb.append(quoteString(dbType, schema)); + sb.append("."); + } + sb.append(quoteString(dbType, table)); - if (i < columns.size() - 1) { - sb.append(","); - } - } - sb.append(" FROM "); - if (null != schema && !schema.isEmpty()) { - sb.append(quoteString(dbtype, schema)); - sb.append("."); - } - sb.append(quoteString(dbtype, table)); + return sb.toString(); + } - return sb.toString(); - } + private static String quoteString(DatabaseTypeEnum dbType, String keyName) { + if (dbType == DatabaseTypeEnum.MYSQL || dbType == DatabaseTypeEnum.MARIADB) { + return String.format("`%s`", keyName); + } else if (dbType == DatabaseTypeEnum.SQLSERVER || dbType == DatabaseTypeEnum.SQLSERVER2000) { + return String.format("[%s]", keyName); + } else { + return String.format("\"%s\"", keyName); + } + } - private static String quoteString(DatabaseTypeEnum dbtype, String keyName) { - if (dbtype == DatabaseTypeEnum.MYSQL) { - return String.format("`%s`", keyName); - } else if (dbtype == DatabaseTypeEnum.SQLSERVER) { - return String.format("[%s]", keyName); - } else { - return String.format("\"%s\"", keyName); - } - } - - public static String getQuotationChar(DatabaseTypeEnum dbtype) { - if (dbtype == DatabaseTypeEnum.MYSQL) { - return "`"; - } else { - return "\""; - } - } } diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/constant/Const.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/constant/Const.java index c9916b86..90d30e10 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/constant/Const.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/constant/Const.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.constant; @@ -71,7 +71,6 @@ public final class Const { * Constructor Function */ private Const() { - } } diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/constant/DBTableType.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/constant/DBTableType.java index 234fbb66..4b0f66cc 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/constant/DBTableType.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/constant/DBTableType.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.constant; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/AbstractDatabase.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/AbstractDatabase.java index de4c89dd..7dd167af 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/AbstractDatabase.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/AbstractDatabase.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/DatabaseFactory.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/DatabaseFactory.java index 83c42913..be96cd83 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/DatabaseFactory.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/DatabaseFactory.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/IDatabaseInterface.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/IDatabaseInterface.java index 7bbab6e6..0d6dfab9 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/IDatabaseInterface.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/IDatabaseInterface.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseDB2Impl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseDB2Impl.java index 623263a5..f5b74e78 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseDB2Impl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseDB2Impl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; @@ -16,6 +16,7 @@ import com.gitee.dbswitch.core.database.AbstractDatabase; import com.gitee.dbswitch.core.database.IDatabaseInterface; import com.gitee.dbswitch.core.model.ColumnDescription; import com.gitee.dbswitch.core.model.ColumnMetaData; +import org.springframework.util.CollectionUtils; /** * 支持DB2数据库的元信息实现 @@ -117,7 +118,7 @@ public class DatabaseDB2Impl extends AbstractDatabase implements IDatabaseInterf retval += ")"; } - if (null != pks && pks.contains(fieldname)) { + if (!CollectionUtils.isEmpty(pks) && pks.contains(fieldname)) { retval += " NOT NULL"; } diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseDmImpl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseDmImpl.java index 81ca9094..3c89695d 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseDmImpl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseDmImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseGreenplumImpl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseGreenplumImpl.java index 10995831..4927a5b1 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseGreenplumImpl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseGreenplumImpl.java @@ -4,11 +4,12 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; +import java.util.Collections; import java.util.List; import com.alibaba.druid.sql.SQLUtils; import com.gitee.dbswitch.core.constant.Const; @@ -17,6 +18,7 @@ import com.gitee.dbswitch.core.database.AbstractDatabase; import com.gitee.dbswitch.core.database.IDatabaseInterface; import com.gitee.dbswitch.core.model.ColumnDescription; import com.gitee.dbswitch.core.model.ColumnMetaData; +import org.springframework.util.CollectionUtils; /** * 支持Greenplum数据库的元信息实现 @@ -76,7 +78,7 @@ public class DatabaseGreenplumImpl extends AbstractDatabase implements IDatabase case ColumnMetaData.TYPE_NUMBER: case ColumnMetaData.TYPE_INTEGER: case ColumnMetaData.TYPE_BIGNUMBER: - if (null!=pks && pks.contains(fieldname)) { + if (!CollectionUtils.isEmpty(pks) && pks.contains(fieldname)) { if (useAutoInc) { retval += "BIGSERIAL"; } else { diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseKingbaseImpl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseKingbaseImpl.java index a01e0313..26243e25 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseKingbaseImpl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseKingbaseImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; @@ -17,6 +17,7 @@ import com.gitee.dbswitch.core.database.AbstractDatabase; import com.gitee.dbswitch.core.database.IDatabaseInterface; import com.gitee.dbswitch.core.model.ColumnDescription; import com.gitee.dbswitch.core.model.ColumnMetaData; +import org.springframework.util.CollectionUtils; /** * 支持Kingbase数据库的元信息实现 @@ -76,7 +77,7 @@ public class DatabaseKingbaseImpl extends AbstractDatabase implements IDatabaseI case ColumnMetaData.TYPE_NUMBER: case ColumnMetaData.TYPE_INTEGER: case ColumnMetaData.TYPE_BIGNUMBER: - if (null != pks && pks.contains(fieldname)) { + if (!CollectionUtils.isEmpty(pks) && pks.contains(fieldname)) { if (useAutoInc) { retval += "BIGSERIAL"; } else { diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseMariaDBImpl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseMariaDBImpl.java index 4c4ed365..1ea59d45 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseMariaDBImpl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseMariaDBImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseMysqlImpl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseMysqlImpl.java index 244a9cee..960d2096 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseMysqlImpl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseMysqlImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; @@ -26,6 +26,7 @@ import com.gitee.dbswitch.core.model.ColumnMetaData; import com.gitee.dbswitch.core.model.TableDescription; import com.gitee.dbswitch.core.util.JdbcOperatorUtils; import com.gitee.dbswitch.core.util.JdbcUrlUtils; +import org.springframework.util.CollectionUtils; /** * 支持MySQL数据库的元信息实现 @@ -145,7 +146,7 @@ public class DatabaseMysqlImpl extends AbstractDatabase implements IDatabaseInte case ColumnMetaData.TYPE_NUMBER: case ColumnMetaData.TYPE_INTEGER: case ColumnMetaData.TYPE_BIGNUMBER: - if (null!=pks && pks.contains(fieldname)) { + if (!CollectionUtils.isEmpty(pks) && pks.contains(fieldname)) { if (useAutoInc) { retval += "BIGINT AUTO_INCREMENT NOT NULL"; } else { @@ -188,7 +189,7 @@ public class DatabaseMysqlImpl extends AbstractDatabase implements IDatabaseInte retval += "CHAR(1)"; } else if (length < 256) { retval += "VARCHAR(" + length + ")"; - }else if (null!=pks && pks.contains(fieldname)) { + }else if (!CollectionUtils.isEmpty(pks) && pks.contains(fieldname)) { /* * MySQL5.6中varchar字段为主键时最大长度为254,例如如下的建表语句在MySQL5.7下能通过,但在MySQL5.6下无法通过: * create table `t_test`( @@ -226,7 +227,7 @@ public class DatabaseMysqlImpl extends AbstractDatabase implements IDatabaseInte @Override public String getPrimaryKeyAsString(List pks) { - if (!pks.isEmpty()) { + if (!CollectionUtils.isEmpty(pks)) { StringBuilder sb = new StringBuilder(); sb.append("`"); sb.append(StringUtils.join(pks, "` , `")); diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseOracleImpl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseOracleImpl.java index 015bcd12..741ead38 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseOracleImpl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseOracleImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; @@ -45,7 +45,7 @@ public class DatabaseOracleImpl extends AbstractDatabase implements IDatabaseInt @Override public List queryTableList(String schemaName) { - List ret = new ArrayList(); + List ret = new ArrayList<>(); String sql = String.format( "SELECT \"OWNER\",\"TABLE_NAME\",\"TABLE_TYPE\",\"COMMENTS\" from all_tab_comments where \"OWNER\"='%s'", schemaName); @@ -84,7 +84,7 @@ public class DatabaseOracleImpl extends AbstractDatabase implements IDatabaseInt // Oracle表的主键可以使用如下命令设置主键是否生效 // 使主键失效:alter table tableName disable primary key; // 使主键恢复:alter table tableName enable primary key; - Set ret = new HashSet(); + Set ret = new HashSet<>(); String sql = String.format("SELECT COLUMN_NAME FROM user_cons_columns WHERE owner='%s' and constraint_name = " + "(SELECT constraint_name FROM user_constraints WHERE table_name = '%s' AND constraint_type = 'P' and STATUS='ENABLED') ", schemaName, tableName); @@ -173,7 +173,7 @@ public class DatabaseOracleImpl extends AbstractDatabase implements IDatabaseInt } else { if (length == 1) { retval.append("NVARCHAR2(1)"); - } else if (length > 0) { + } else if (length > 0 && length < 2000) { // VARCHAR2(size),size最大值为4000,单位是字节;而NVARCHAR2(size),size最大值为2000,单位是字符 retval.append("NVARCHAR2(").append(length).append(')'); } else { diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabasePostgresImpl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabasePostgresImpl.java index 6582d7f8..1362c7a6 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabasePostgresImpl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabasePostgresImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; @@ -17,6 +17,7 @@ import com.gitee.dbswitch.core.database.AbstractDatabase; import com.gitee.dbswitch.core.database.IDatabaseInterface; import com.gitee.dbswitch.core.model.ColumnDescription; import com.gitee.dbswitch.core.model.ColumnMetaData; +import org.springframework.util.CollectionUtils; /** * 支持PostgreSQL数据库的元信息实现 @@ -76,7 +77,7 @@ public class DatabasePostgresImpl extends AbstractDatabase implements IDatabaseI case ColumnMetaData.TYPE_NUMBER: case ColumnMetaData.TYPE_INTEGER: case ColumnMetaData.TYPE_BIGNUMBER: - if (null != pks && pks.contains(fieldname)) { + if (!CollectionUtils.isEmpty(pks) && pks.contains(fieldname)) { if (useAutoInc) { retval += "BIGSERIAL"; } else { @@ -112,7 +113,7 @@ public class DatabasePostgresImpl extends AbstractDatabase implements IDatabaseI if (length < 1 || length >= AbstractDatabase.CLOB_LENGTH) { retval += "TEXT"; } else { - if (null != pks && pks.contains(fieldname)) { + if (!CollectionUtils.isEmpty(pks) && pks.contains(fieldname)) { retval += "VARCHAR(" + length + ")"; } else { retval += "TEXT"; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseSqlserver2000Impl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseSqlserver2000Impl.java index 6a97cc13..cb4add09 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseSqlserver2000Impl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseSqlserver2000Impl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseSqlserverImpl.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseSqlserverImpl.java index 3dbdbb05..0a69d7dc 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseSqlserverImpl.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/database/impl/DatabaseSqlserverImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.core.database.impl; @@ -26,6 +26,7 @@ import com.gitee.dbswitch.core.model.ColumnDescription; import com.gitee.dbswitch.core.model.ColumnMetaData; import com.gitee.dbswitch.core.model.TableDescription; import com.gitee.dbswitch.core.util.JdbcOperatorUtils; +import org.springframework.util.CollectionUtils; /** * 支持SQLServer数据库的元信息实现 @@ -87,7 +88,6 @@ public class DatabaseSqlserverImpl extends AbstractDatabase implements IDatabase try { if (null != schemas) { schemas.close(); - schemas = null; } } catch (SQLException e) { } @@ -228,7 +228,7 @@ public class DatabaseSqlserverImpl extends AbstractDatabase implements IDatabase case ColumnMetaData.TYPE_NUMBER: case ColumnMetaData.TYPE_INTEGER: case ColumnMetaData.TYPE_BIGNUMBER: - if (null != pks && pks.contains(fieldname)) { + if (!CollectionUtils.isEmpty(pks) && pks.contains(fieldname)) { if (useAutoInc) { retval += "BIGINT IDENTITY(0,1)"; } else { @@ -288,7 +288,7 @@ public class DatabaseSqlserverImpl extends AbstractDatabase implements IDatabase @Override public String getPrimaryKeyAsString(List pks) { - if (!pks.isEmpty()) { + if (!CollectionUtils.isEmpty(pks)) { StringBuilder sb = new StringBuilder(); sb.append("["); sb.append(StringUtils.join(pks, "] , [")); diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/ColumnDescription.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/ColumnDescription.java index 42631746..10e6b1bb 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/ColumnDescription.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/ColumnDescription.java @@ -13,8 +13,8 @@ import com.gitee.dbswitch.common.constant.DatabaseTypeEnum; /** * 数据库列描述符信息定义(Column Description) - * @author tang * + * @author tang */ public class ColumnDescription { diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/ColumnMetaData.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/ColumnMetaData.java index 7b92e0be..acacc763 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/ColumnMetaData.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/ColumnMetaData.java @@ -14,6 +14,7 @@ import com.gitee.dbswitch.core.database.AbstractDatabase; /** * 数据库表列的元信息 + * * @author tang * */ @@ -81,10 +82,7 @@ public class ColumnMetaData { /** * Constructor function * - * @param name - * @param type - * @param length - * @param precision + * @param desc */ public ColumnMetaData(ColumnDescription desc) { this.create(desc); @@ -257,7 +255,7 @@ public class ColumnMetaData { length = desc.getDisplaySize(); break; - case java.sql.Types.LONGVARCHAR: // Character Large Object + case java.sql.Types.LONGVARCHAR: case java.sql.Types.CLOB: case java.sql.Types.NCLOB: valtype = ColumnMetaData.TYPE_STRING; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/DatabaseDescription.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/DatabaseDescription.java index 474fc412..f24656c5 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/DatabaseDescription.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/DatabaseDescription.java @@ -13,6 +13,7 @@ import com.gitee.dbswitch.common.constant.DatabaseTypeEnum; /** * 数据库连接描述符信息定义(Database Description) + * * @author tang * */ @@ -20,7 +21,8 @@ public class DatabaseDescription { protected DatabaseTypeEnum type; protected String host; protected int port; - protected String mode;//对于Oracle数据库的模式,可取范围为:sid,servicename,tnsname三种 + /** 对于Oracle数据库的模式,可取范围为:sid,serviceName,TNSName三种 */ + protected String mode; protected String dbname; protected String charset; protected String username; diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/TableDescription.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/TableDescription.java index 30ed2891..205fccb4 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/TableDescription.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/model/TableDescription.java @@ -13,6 +13,7 @@ import com.gitee.dbswitch.core.constant.DBTableType; /** * 数据库表描述符信息定义(Table Description) + * * @author tang * */ diff --git a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/util/GenerateSqlUtils.java b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/util/GenerateSqlUtils.java index e0b933d1..50363970 100644 --- a/dbswitch-core/src/main/java/com/gitee/dbswitch/core/util/GenerateSqlUtils.java +++ b/dbswitch-core/src/main/java/com/gitee/dbswitch/core/util/GenerateSqlUtils.java @@ -11,7 +11,6 @@ package com.gitee.dbswitch.core.util; import java.util.List; import java.util.stream.Collectors; - import com.gitee.dbswitch.common.constant.DatabaseTypeEnum; import com.gitee.dbswitch.core.constant.Const; import com.gitee.dbswitch.core.database.AbstractDatabase; @@ -30,8 +29,10 @@ public class GenerateSqlUtils { public static String getDDLCreateTableSQL(DatabaseTypeEnum type, List fieldNames, List primaryKeys, String schemaName, String tableName, boolean autoIncr) { StringBuilder retval = new StringBuilder(); - List pks = fieldNames.stream().filter((cd) -> primaryKeys.contains(cd.getFieldName())) - .map((cd) -> cd.getFieldName()).collect(Collectors.toList()); + List pks = fieldNames.stream() + .filter((cd) -> primaryKeys.contains(cd.getFieldName())) + .map((cd) -> cd.getFieldName()) + .collect(Collectors.toList()); AbstractDatabase db = DatabaseFactory.getDatabaseInstance(type); diff --git a/dbswitch-data/pom.xml b/dbswitch-data/pom.xml index 4f83b9d1..3f43c750 100644 --- a/dbswitch-data/pom.xml +++ b/dbswitch-data/pom.xml @@ -62,6 +62,12 @@ postgresql + + com.carrotsearch + java-sizeof + 0.0.5 + + org.springframework.boot spring-boot-configuration-processor diff --git a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/DataSyncApplication.java b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/DataSyncApplication.java index aa40018d..6f4f2235 100644 --- a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/DataSyncApplication.java +++ b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/DataSyncApplication.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.data; diff --git a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/config/DbswichProperties.java b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/config/DbswichProperties.java index e97187cd..52f158db 100644 --- a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/config/DbswichProperties.java +++ b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/config/DbswichProperties.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.data.config; diff --git a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/config/PropertiesConfig.java b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/config/PropertiesConfig.java index aaad2cef..10fce7a9 100644 --- a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/config/PropertiesConfig.java +++ b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/config/PropertiesConfig.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.data.config; diff --git a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/service/MainService.java b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/service/MainService.java index 65733f75..7f46b6c2 100644 --- a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/service/MainService.java +++ b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/service/MainService.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.data.service; @@ -17,8 +17,8 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.regex.Pattern; - import javax.sql.DataSource; +import com.carrotsearch.sizeof.RamUsageEstimator; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; @@ -58,6 +58,8 @@ import lombok.extern.slf4j.Slf4j; @Service("MainService") public class MainService { + private final long MAX_CACHE_BYTES_SIZE = 512 * 1024 * 1024; + private ObjectMapper jackson = new ObjectMapper(); @Autowired @@ -264,7 +266,8 @@ public class MainService { StatementResultSet srs = sourceOperator.queryTableData(tableDescription.getSchemaName(), tableDescription.getTableName(), fields); - List cache = new LinkedList(); + List cache = new LinkedList<>(); + long cacheBytes=0; long totalCount = 0; try { ResultSet rs = srs.getResultset(); @@ -280,12 +283,14 @@ public class MainService { } cache.add(record); + cacheBytes += RamUsageEstimator.shallowSizeOf(record); ++totalCount; - if (cache.size() >= BATCH_SIZE) { + if (cache.size() >= BATCH_SIZE || cacheBytes >= MAX_CACHE_BYTES_SIZE) { long ret = writer.write(fields, cache); log.info("[FullCoverSynch] handle table [{}] data count: {}", fullTableName, ret); cache.clear(); + cacheBytes = 0; } } @@ -348,6 +353,7 @@ public class MainService { private long countUpdate = 0; private long countDelete = 0; private long count = 0; + private long cacheBytes=0; private List cacheInsert = new LinkedList(); private List cacheUpdate = new LinkedList(); private List cacheDelete = new LinkedList(); @@ -365,6 +371,7 @@ public class MainService { countDelete++; } + cacheBytes+=RamUsageEstimator.shallowSizeOf(record); count++; checkFull(fields); } @@ -376,7 +383,7 @@ public class MainService { */ private void checkFull(List fields) { if (cacheInsert.size() >= BATCH_SIZE || cacheUpdate.size() >= BATCH_SIZE - || cacheDelete.size() >= BATCH_SIZE) { + || cacheDelete.size() >= BATCH_SIZE || cacheBytes >= MAX_CACHE_BYTES_SIZE) { if (cacheDelete.size() > 0) { doDelete(fields); } @@ -388,6 +395,8 @@ public class MainService { if (cacheUpdate.size() > 0) { doUpdate(fields); } + + cacheBytes = 0; } } @@ -433,7 +442,7 @@ public class MainService { /** * 创建于指定数据库连接描述符的连接池 * - * @param dbdesc 数据库连接描述符 + * @param description 数据库连接描述符 * @return HikariDataSource连接池 */ private HikariDataSource createSourceDataSource(DbswichProperties.SourceDataSourceProperties description) { @@ -459,7 +468,7 @@ public class MainService { /** * 创建于指定数据库连接描述符的连接池 * - * @param dbdesc 数据库连接描述符 + * @param description 数据库连接描述符 * @return HikariDataSource连接池 */ private HikariDataSource createTargetDataSource(DbswichProperties.TargetDataSourceProperties description) { @@ -499,15 +508,16 @@ public class MainService { /** * 检查MySQL数据库表的存储引擎是否为Innodb - * + * + * @param shemaName schema名 + * @param tableName table名 * @param dataSource 数据源 - * @param task 任务实体 - * @return 为Innodb存储引擎时返回True,否在为false + * @return 为Innodb存储引擎时返回True, 否在为false */ private boolean isMysqlInodbStorageEngine(String shemaName, String tableName, DataSource dataSource) { String sql = "SELECT count(*) as total FROM information_schema.tables WHERE table_schema=? AND table_name=? AND ENGINE='InnoDB'"; JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); - return jdbcTemplate.queryForObject(sql, new Object[] { shemaName, tableName }, Integer.class) > 0; + return jdbcTemplate.queryForObject(sql, new Object[]{shemaName, tableName}, Integer.class) > 0; } /** diff --git a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/util/JdbcTemplateUtils.java b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/util/JdbcTemplateUtils.java index f4b5b479..df99e0de 100644 --- a/dbswitch-data/src/main/java/com/gitee/dbswitch/data/util/JdbcTemplateUtils.java +++ b/dbswitch-data/src/main/java/com/gitee/dbswitch/data/util/JdbcTemplateUtils.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.data.util; diff --git a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/ChangeCaculatorService.java b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/ChangeCaculatorService.java index 06b6057d..4e831e8f 100644 --- a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/ChangeCaculatorService.java +++ b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/ChangeCaculatorService.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbchange; diff --git a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/IDatabaseChangeCaculator.java b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/IDatabaseChangeCaculator.java index dac7699d..523cf496 100644 --- a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/IDatabaseChangeCaculator.java +++ b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/IDatabaseChangeCaculator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbchange; diff --git a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/IDatabaseRowHandler.java b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/IDatabaseRowHandler.java index efd08588..eb14bdb1 100644 --- a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/IDatabaseRowHandler.java +++ b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/IDatabaseRowHandler.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbchange; diff --git a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/RecordChangeTypeEnum.java b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/RecordChangeTypeEnum.java index 415f7ad4..e4ca1452 100644 --- a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/RecordChangeTypeEnum.java +++ b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/RecordChangeTypeEnum.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbchange; diff --git a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/pojo/TaskParamBean.java b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/pojo/TaskParamBean.java index b54fce02..82f45535 100644 --- a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/pojo/TaskParamBean.java +++ b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/pojo/TaskParamBean.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbchange.pojo; diff --git a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/util/JdbcTypesUtils.java b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/util/JdbcTypesUtils.java index fa255904..8fd1d6e5 100644 --- a/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/util/JdbcTypesUtils.java +++ b/dbswitch-dbchange/src/main/java/com/gitee/dbswitch/dbchange/util/JdbcTypesUtils.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbchange.util; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/constant/Constants.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/constant/Constants.java index 10ce8c92..3c9da910 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/constant/Constants.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/constant/Constants.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.constant; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/AbstractDatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/AbstractDatabaseOperator.java index e0d2eecf..bef279ba 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/AbstractDatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/AbstractDatabaseOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.database; @@ -15,6 +15,7 @@ import java.sql.ResultSet; import java.sql.SQLException; import java.util.Objects; import javax.sql.DataSource; + import org.springframework.jdbc.support.JdbcUtils; import com.gitee.dbswitch.dbcommon.constant.Constants; import com.gitee.dbswitch.dbcommon.pojo.StatementResultSet; @@ -22,94 +23,90 @@ import lombok.extern.slf4j.Slf4j; /** * 数据读取抽象基类 - * - * @author tang * + * @author tang */ @Slf4j public abstract class AbstractDatabaseOperator implements IDatabaseOperator { - protected DataSource dataSource; + protected DataSource dataSource; - protected int fetchSize; + protected int fetchSize; - public AbstractDatabaseOperator(DataSource dataSource) { - this.dataSource = Objects.requireNonNull(dataSource, "数据源非法,为null"); - this.fetchSize = Constants.DEFAULT_FETCH_SIZE; - } + public AbstractDatabaseOperator(DataSource dataSource) { + this.dataSource = Objects.requireNonNull(dataSource, "数据源非法,为null"); + this.fetchSize = Constants.DEFAULT_FETCH_SIZE; + } - @Override - public DataSource getDataSource() { - return this.dataSource; - } + @Override + public DataSource getDataSource() { + return this.dataSource; + } - @Override - public int getFetchSize() { - return this.fetchSize; - } + @Override + public int getFetchSize() { + return this.fetchSize; + } - @Override - public void setFetchSize(int size) { - if (size < Constants.MINIMUM_FETCH_SIZE) { - throw new IllegalArgumentException("设置的批量处理行数的大小fetchSize不得小于" + Constants.MINIMUM_FETCH_SIZE); - } + @Override + public void setFetchSize(int size) { + if (size < Constants.MINIMUM_FETCH_SIZE) { + throw new IllegalArgumentException("设置的批量处理行数的大小fetchSize不得小于" + Constants.MINIMUM_FETCH_SIZE); + } - this.fetchSize = size; - } + this.fetchSize = size; + } - /** - * 已经指定的查询SQL语句查询数据结果集 - * - * @param dataSource 数据源 - * @param sql 查询的SQL语句 - * @param fetchSize 批处理大小 - * @return 结果集包装对象 - */ - protected final StatementResultSet selectTableData(String sql, int fetchSize) { - if (log.isDebugEnabled()) { - log.debug("Query table data sql :{}", sql); - } + /** + * 已经指定的查询SQL语句查询数据结果集 + * + * @param sql 查询的SQL语句 + * @param fetchSize 批处理大小 + * @return 结果集包装对象 + */ + protected final StatementResultSet selectTableData(String sql, int fetchSize) { + if (log.isDebugEnabled()) { + log.debug("Query table data sql :{}", sql); + } - try { - StatementResultSet srs = new StatementResultSet(); - srs.setConnection(dataSource.getConnection()); - srs.setAutoCommit(srs.getConnection().getAutoCommit()); - srs.getConnection().setAutoCommit(false); - srs.setStatement( - srs.getConnection().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)); - srs.getStatement().setQueryTimeout(Constants.DEFAULT_QUERY_TIMEOUT_SECONDS); - srs.getStatement().setFetchSize(fetchSize); - srs.setResultset(srs.getStatement().executeQuery(sql)); - return srs; - } catch (Throwable t) { - throw new RuntimeException(t); - } - } + try { + StatementResultSet srs = new StatementResultSet(); + srs.setConnection(dataSource.getConnection()); + srs.setAutoCommit(srs.getConnection().getAutoCommit()); + srs.getConnection().setAutoCommit(false); + srs.setStatement(srs.getConnection().createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY)); + srs.getStatement().setQueryTimeout(Constants.DEFAULT_QUERY_TIMEOUT_SECONDS); + srs.getStatement().setFetchSize(fetchSize); + srs.setResultset(srs.getStatement().executeQuery(sql)); + return srs; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } - /** - * 执行写SQL操作 - * - * @param dataSource 数据源 - * @param sql 写SQL语句 - */ - protected final int executeSql(String sql) { - Connection connection = null; - PreparedStatement pstmt = null; + /** + * 执行写SQL操作 + * + * @param sql 写SQL语句 + */ + protected final int executeSql(String sql) { + Connection connection = null; + PreparedStatement pstmt = null; - if (log.isDebugEnabled()) { - log.debug("Execute sql :{}", sql); - } + if (log.isDebugEnabled()) { + log.debug("Execute sql :{}", sql); + } - try { - connection = dataSource.getConnection(); - pstmt = connection.prepareStatement(sql); - return pstmt.executeUpdate(); - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - JdbcUtils.closeStatement(pstmt); - JdbcUtils.closeConnection(connection); - } - } + try { + connection = dataSource.getConnection(); + pstmt = connection.prepareStatement(sql); + return pstmt.executeUpdate(); + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + JdbcUtils.closeStatement(pstmt); + JdbcUtils.closeConnection(connection); + } + } } diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/DatabaseOperatorFactory.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/DatabaseOperatorFactory.java index 08a9b41b..20a7628b 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/DatabaseOperatorFactory.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/DatabaseOperatorFactory.java @@ -4,14 +4,14 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.database; import java.util.Map; -import java.lang.reflect.Constructor; import java.util.HashMap; +import java.util.function.Function; import javax.sql.DataSource; import com.gitee.dbswitch.dbcommon.database.impl.DB2DatabaseOperator; import com.gitee.dbswitch.dbcommon.database.impl.DmDatabaseOperator; @@ -25,50 +25,40 @@ import com.gitee.dbswitch.dbcommon.util.DatabaseAwareUtils; /** * 数据库操作器构造工厂类 - * - * @author tang * + * @author tang */ public final class DatabaseOperatorFactory { - private static final Map DATABASE_OPERATOR_MAPPER = new HashMap() { + private static final Map> DATABASE_OPERATOR_MAPPER = new HashMap>() { - private static final long serialVersionUID = -5278835613240515265L; + private static final long serialVersionUID = -5278835613240515265L; - { - put("MYSQL", MysqlDatabaseOperator.class.getName()); - put("ORACLE", OracleDatabaseOperator.class.getName()); - put("SQLSERVER", SqlServerDatabaseOperator.class.getName()); - put("POSTGRESQL", PostgreSqlDatabaseOperator.class.getName()); - put("GREENPLUM", GreenplumDatabaseOperator.class.getName()); - put("DB2", DB2DatabaseOperator.class.getName()); - put("DM", DmDatabaseOperator.class.getName()); - put("KINGBASE", KingbaseDatabaseOperator.class.getName()); - } - }; + { + put("MYSQL", MysqlDatabaseOperator::new); + put("ORACLE", OracleDatabaseOperator::new); + put("SQLSERVER", SqlServerDatabaseOperator::new); + put("POSTGRESQL", PostgreSqlDatabaseOperator::new); + put("GREENPLUM", GreenplumDatabaseOperator::new); + put("DB2", DB2DatabaseOperator::new); + put("DM", DmDatabaseOperator::new); + put("KINGBASE", KingbaseDatabaseOperator::new); + } + }; - /** - * 根据数据源获取数据的读取操作器 - * - * @param dataSource 数据库源 - * @return 指定类型的数据库读取器 - */ - public static IDatabaseOperator createDatabaseOperator(DataSource dataSource) { - String type = DatabaseAwareUtils.getDatabaseNameByDataSource(dataSource).toUpperCase(); - if (DATABASE_OPERATOR_MAPPER.containsKey(type)) { - String className = DATABASE_OPERATOR_MAPPER.get(type); - try { - Class clazz = Class.forName(className); - Class[] paraTypes = { DataSource.class }; - Object[] paraValues = { dataSource }; - Constructor cons = clazz.getConstructor(paraTypes); - return (IDatabaseOperator) cons.newInstance(paraValues); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + /** + * 根据数据源获取数据的读取操作器 + * + * @param dataSource 数据库源 + * @return 指定类型的数据库读取器 + */ + public static IDatabaseOperator createDatabaseOperator(DataSource dataSource) { + String type = DatabaseAwareUtils.getDatabaseNameByDataSource(dataSource).toUpperCase(); + if (!DATABASE_OPERATOR_MAPPER.containsKey(type)) { + throw new RuntimeException(String.format("[dbcommon] Unkown Supported database type (%s)", type)); + } - throw new RuntimeException(String.format("[dbcommon] Unkown Supported database type (%s)", type)); - } + return DATABASE_OPERATOR_MAPPER.get(type).apply(dataSource); + } } diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/IDatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/IDatabaseOperator.java index 5759197d..b94c80cf 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/IDatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/IDatabaseOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.database; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/DB2DatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/DB2DatabaseOperator.java index 2c894590..e9840888 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/DB2DatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/DB2DatabaseOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.database.impl; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/DmDatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/DmDatabaseOperator.java index 30362e5b..d73dd962 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/DmDatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/DmDatabaseOperator.java @@ -1,8 +1,23 @@ +// 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.dbcommon.database.impl; import javax.sql.DataSource; import com.gitee.dbswitch.dbcommon.database.IDatabaseOperator; +/** + * DM数据库实现类 + * + * @author tang + * + */ public class DmDatabaseOperator extends OracleDatabaseOperator implements IDatabaseOperator { public DmDatabaseOperator(DataSource dataSource) { diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/GreenplumDatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/GreenplumDatabaseOperator.java index 8e91d397..76ca19ad 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/GreenplumDatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/GreenplumDatabaseOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.database.impl; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/KingbaseDatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/KingbaseDatabaseOperator.java index 02ba4fee..c8177d5d 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/KingbaseDatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/KingbaseDatabaseOperator.java @@ -1,5 +1,20 @@ +// 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.dbcommon.database.impl; +/** + * Kingbase8数据库实现类 + * + * @author tang + * + */ import javax.sql.DataSource; import com.gitee.dbswitch.dbcommon.database.IDatabaseOperator; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/MysqlDatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/MysqlDatabaseOperator.java index f6574a55..7e07da7f 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/MysqlDatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/MysqlDatabaseOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.database.impl; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/OracleDatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/OracleDatabaseOperator.java index 4b9c1971..412b23bc 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/OracleDatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/OracleDatabaseOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.database.impl; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/PostgreSqlDatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/PostgreSqlDatabaseOperator.java index d2e4ab88..3e4a5413 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/PostgreSqlDatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/PostgreSqlDatabaseOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.database.impl; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/SqlServerDatabaseOperator.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/SqlServerDatabaseOperator.java index a70f1578..111164c6 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/SqlServerDatabaseOperator.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/database/impl/SqlServerDatabaseOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.database.impl; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/pojo/StatementResultSet.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/pojo/StatementResultSet.java index cbdc6fae..fcf055bc 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/pojo/StatementResultSet.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/pojo/StatementResultSet.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.pojo; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/util/DatabaseAwareUtils.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/util/DatabaseAwareUtils.java index a3b0ec71..b7243f7e 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/util/DatabaseAwareUtils.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/util/DatabaseAwareUtils.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.util; diff --git a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/util/JdbcMetaDataUtils.java b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/util/JdbcMetaDataUtils.java index e865cbf7..9b6e1220 100644 --- a/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/util/JdbcMetaDataUtils.java +++ b/dbswitch-dbcommon/src/main/java/com/gitee/dbswitch/dbcommon/util/JdbcMetaDataUtils.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbcommon.util; @@ -53,7 +53,7 @@ public class JdbcMetaDataUtils { String columnName = columns.getString("COLUMN_NAME"); result.add(columnName); } - return new ArrayList(result); + return new ArrayList<>(result); } catch (Throwable t) { throw new RuntimeException(t); } finally { @@ -70,7 +70,7 @@ public class JdbcMetaDataUtils { * @return 主键字段名称列表 */ public List queryTablePrimaryKeys(String schemaName, String tableName) { - Set result = new HashSet(); + Set result = new HashSet<>(); Connection connection = null; try { @@ -81,7 +81,7 @@ public class JdbcMetaDataUtils { String columnName = columns.getString("COLUMN_NAME"); result.add(columnName); } - return new ArrayList(result); + return new ArrayList<>(result); } catch (Throwable t) { throw new RuntimeException(t); } finally { diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/AbstractDatabaseSynchronize.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/AbstractDatabaseSynchronize.java index 6446da5e..2143f895 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/AbstractDatabaseSynchronize.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/AbstractDatabaseSynchronize.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch; @@ -12,7 +12,6 @@ package com.gitee.dbswitch.dbsynch; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; -import java.sql.SQLException; import java.sql.Statement; import java.util.ArrayList; import java.util.HashMap; @@ -20,8 +19,6 @@ import java.util.LinkedList; import java.util.List; import java.util.Map; import javax.sql.DataSource; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.ConnectionCallback; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.support.JdbcUtils; @@ -34,276 +31,255 @@ import lombok.extern.slf4j.Slf4j; /** * 数据同步抽象基类 - * - * @author tang * + * @author tang */ @Slf4j public abstract class AbstractDatabaseSynchronize implements IDatabaseSynchronize { - - private DefaultTransactionDefinition defination; - - private JdbcTemplate jdbcTemplate; - - private PlatformTransactionManager transactionManager; - - //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// - - private Map columnType; - - protected List fieldOrders; - - protected List pksOrders; - - protected String insertStatementSql; - - protected String updateStatementSql; - - protected String deleteStatementSql; - - protected int[] insertArgsType; - - protected int[] updateArgsType; - - protected int[] deleteArgsType; - - public AbstractDatabaseSynchronize(DataSource ds) { - this.defination= new DefaultTransactionDefinition(); - this.defination.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); - this.defination.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - - this.jdbcTemplate=new JdbcTemplate(ds); - - this.transactionManager = new DataSourceTransactionManager(ds); - - this.columnType=new HashMap<>(); - } - @Override - public DataSource getDataSource() { - return this.jdbcTemplate.getDataSource(); - } - - /** - * 获取查询列元信息的SQL语句 - * - * @param schemaName 模式名称 - * @param tableName 表名称 - * @return SQL语句 - */ - public abstract String getColumMetaDataSql(String schemaName, String tableName); + private DefaultTransactionDefinition defination; + private JdbcTemplate jdbcTemplate; + private PlatformTransactionManager transactionManager; + private Map columnType; + protected List fieldOrders; + protected List pksOrders; + protected String insertStatementSql; + protected String updateStatementSql; + protected String deleteStatementSql; + protected int[] insertArgsType; + protected int[] updateArgsType; + protected int[] deleteArgsType; - /** - * 生成Insert操作的SQL语句 - * - * @param schemaName 模式名称 - * @param tableName 表名称 - * @param fieldNames 字段列表 - * @return Insert操作的SQL语句 - */ - public abstract String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames); - - /** - * 生成Update操作的SQL语句 - * - * @param schemaName 模式名称 - * @param tableName 表名称 - * @param fieldNames 字段列表 - * @param pks 主键列表 - * @return Update操作的SQL语句 - */ - public abstract String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, List pks); + public AbstractDatabaseSynchronize(DataSource ds) { + this.defination = new DefaultTransactionDefinition(); + this.defination.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); + this.defination.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - /** - * 生成Delete操作的SQL语句 - * - * @param schemaName 模式名称 - * @param tableName 表名称 - * @param pks 主键列表 - * @return Delete操作的SQL语句 - */ - public abstract String getDeletePrepareStatementSql(String schemaName, String tableName, List pks); + this.jdbcTemplate = new JdbcTemplate(ds); + this.transactionManager = new DataSourceTransactionManager(ds); + this.columnType = new HashMap<>(); + } - @Override - public void prepare(String schemaName, String tableName, List fieldNames, List pks) { - if (fieldNames.isEmpty() || pks.isEmpty() || fieldNames.size() < pks.size()) { - throw new IllegalArgumentException("字段列表和主键列表不能为空,或者字段总个数应不小于主键总个数"); - } + @Override + public DataSource getDataSource() { + return this.jdbcTemplate.getDataSource(); + } - if (!fieldNames.containsAll(pks)) { - throw new IllegalArgumentException("字段列表必须包含主键列表"); - } + /** + * 获取查询列元信息的SQL语句 + * + * @param schemaName 模式名称 + * @param tableName 表名称 + * @return SQL语句 + */ + public abstract String getColumnMetaDataSql(String schemaName, String tableName); - String sql = this.getColumMetaDataSql(schemaName, tableName); - columnType.clear(); + /** + * 生成Insert操作的SQL语句 + * + * @param schemaName 模式名称 + * @param tableName 表名称 + * @param fieldNames 字段列表 + * @return Insert操作的SQL语句 + */ + public abstract String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames); - this.jdbcTemplate.execute(new ConnectionCallback() { + /** + * 生成Update操作的SQL语句 + * + * @param schemaName 模式名称 + * @param tableName 表名称 + * @param fieldNames 字段列表 + * @param pks 主键列表 + * @return Update操作的SQL语句 + */ + public abstract String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, List pks); - @Override - public Boolean doInConnection(Connection conn) throws SQLException, DataAccessException { - Statement stmt = null; - ResultSet rs = null; - try { - stmt = conn.createStatement(); - rs = stmt.executeQuery(sql); - ResultSetMetaData rsMetaData = rs.getMetaData(); - for (int i = 0, len = rsMetaData.getColumnCount(); i < len; i++) { - columnType.put(rsMetaData.getColumnName(i + 1), rsMetaData.getColumnType(i + 1)); - } + /** + * 生成Delete操作的SQL语句 + * + * @param schemaName 模式名称 + * @param tableName 表名称 + * @param pks 主键列表 + * @return Delete操作的SQL语句 + */ + public abstract String getDeletePrepareStatementSql(String schemaName, String tableName, List pks); - return true; - } catch (Exception e) { - throw new RuntimeException( - String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName), e); - } finally { - JdbcUtils.closeResultSet(rs); - JdbcUtils.closeStatement(stmt); - } - } - }); + @Override + public void prepare(String schemaName, String tableName, List fieldNames, List pks) { + if (fieldNames.isEmpty() || pks.isEmpty() || fieldNames.size() < pks.size()) { + throw new IllegalArgumentException("字段列表和主键列表不能为空,或者字段总个数应不小于主键总个数"); + } - this.fieldOrders = new ArrayList(fieldNames); - this.pksOrders = new ArrayList(pks); + if (!fieldNames.containsAll(pks)) { + throw new IllegalArgumentException("字段列表必须包含主键列表"); + } - this.insertStatementSql = this.getInsertPrepareStatementSql(schemaName, tableName, fieldNames); - this.updateStatementSql = this.getUpdatePrepareStatementSql(schemaName, tableName, fieldNames, pks); - this.deleteStatementSql = this.getDeletePrepareStatementSql(schemaName, tableName, pks); + String sql = this.getColumnMetaDataSql(schemaName, tableName); + columnType.clear(); - insertArgsType = new int[fieldNames.size()]; - for (int k = 0; k < fieldNames.size(); ++k) { - String field = fieldNames.get(k); - insertArgsType[k] = this.columnType.get(field); - } + this.jdbcTemplate.execute((Connection conn) -> { + Statement stmt = null; + ResultSet rs = null; + try { + stmt = conn.createStatement(); + rs = stmt.executeQuery(sql); + ResultSetMetaData rsMetaData = rs.getMetaData(); + for (int i = 0, len = rsMetaData.getColumnCount(); i < len; i++) { + columnType.put(rsMetaData.getColumnName(i + 1), rsMetaData.getColumnType(i + 1)); + } - updateArgsType = new int[fieldNames.size()]; - int idx = 0; - for (int i = 0; i < fieldNames.size(); ++i) { - String field = fieldNames.get(i); - if (!pks.contains(field)) { - updateArgsType[idx++] = this.columnType.get(field); - } - } - for (String pk : pks) { - updateArgsType[idx++] = this.columnType.get(pk); - } + return true; + } catch (Exception e) { + throw new RuntimeException(String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName), e); + } finally { + JdbcUtils.closeResultSet(rs); + JdbcUtils.closeStatement(stmt); + } + }); - deleteArgsType = new int[pks.size()]; - for (int j = 0; j < pks.size(); ++j) { - String pk = pks.get(j); - deleteArgsType[j] = this.columnType.get(pk); - } - } - - @Override - public long executeInsert(List records) { - TransactionStatus status = transactionManager.getTransaction(defination); - if (log.isDebugEnabled()) { - log.debug("Execute Insert SQL : {}", this.insertStatementSql); - } + this.fieldOrders = new ArrayList(fieldNames); + this.pksOrders = new ArrayList(pks); - try { - int[] affects = jdbcTemplate.batchUpdate(this.insertStatementSql, records, this.insertArgsType); - int affectCount = 0; - for (int i : affects) { - affectCount += i; - } + this.insertStatementSql = this.getInsertPrepareStatementSql(schemaName, tableName, fieldNames); + this.updateStatementSql = this.getUpdatePrepareStatementSql(schemaName, tableName, fieldNames, pks); + this.deleteStatementSql = this.getDeletePrepareStatementSql(schemaName, tableName, pks); - transactionManager.commit(status); - return affectCount; - } catch (TransactionException e) { - transactionManager.rollback(status); - throw e; - } catch (Exception e) { - transactionManager.rollback(status); - throw e; - } - } + insertArgsType = new int[fieldNames.size()]; + for (int k = 0; k < fieldNames.size(); ++k) { + String field = fieldNames.get(k); + insertArgsType[k] = this.columnType.get(field); + } - @Override - public long executeUpdate(List records) { - List datas = new LinkedList(); - for (Object[] r : records) { - - Object[] nr = new Object[this.fieldOrders.size()]; - int idx=0; - - for (int i = 0; i < this.fieldOrders.size(); ++i) { - String field = this.fieldOrders.get(i); - if(!this.pksOrders.contains(field)) { - int index = this.fieldOrders.indexOf(field); - nr[idx++] = r[index]; - } - } - - for(int j=0;j records) { + TransactionStatus status = transactionManager.getTransaction(defination); + if (log.isDebugEnabled()) { + log.debug("Execute Insert SQL : {}", this.insertStatementSql); + } - @Override - public long executeDelete(List records) { - List datas = new LinkedList(); - for (Object[] r : records) { - Object[] nr = new Object[this.pksOrders.size()]; - for (int i = 0; i < this.pksOrders.size(); ++i) { - String pk = this.pksOrders.get(i); - int index = this.fieldOrders.indexOf(pk); - nr[i] = r[index]; - } + try { + int[] affects = jdbcTemplate.batchUpdate(this.insertStatementSql, records, this.insertArgsType); + int affectCount = 0; + for (int i : affects) { + affectCount += i; + } - datas.add(nr); - } + transactionManager.commit(status); + return affectCount; + } catch (TransactionException e) { + transactionManager.rollback(status); + throw e; + } catch (Exception e) { + transactionManager.rollback(status); + throw e; + } + } - TransactionStatus status = transactionManager.getTransaction(defination); - if (log.isDebugEnabled()) { - log.debug("Execute Delete SQL : {}", this.deleteStatementSql); - } + @Override + public long executeUpdate(List records) { + List datas = new LinkedList<>(); + for (Object[] r : records) { - try { - int[] affects = jdbcTemplate.batchUpdate(this.deleteStatementSql, datas, this.deleteArgsType); - int affectCount = 0; - for (int i : affects) { - affectCount += i; - } + Object[] nr = new Object[this.fieldOrders.size()]; + int idx = 0; - transactionManager.commit(status); - return affectCount; - } catch (TransactionException e) { - transactionManager.rollback(status); - throw e; - } catch (Exception e) { - transactionManager.rollback(status); - throw e; - } finally { - datas.clear(); - } - } + for (int i = 0; i < this.fieldOrders.size(); ++i) { + String field = this.fieldOrders.get(i); + if (!this.pksOrders.contains(field)) { + int index = this.fieldOrders.indexOf(field); + nr[idx++] = r[index]; + } + } + + for (int j = 0; j < this.pksOrders.size(); ++j) { + String pk = this.pksOrders.get(j); + int index = this.fieldOrders.indexOf(pk); + nr[idx++] = r[index]; + } + + datas.add(nr); + } + + TransactionStatus status = transactionManager.getTransaction(defination); + if (log.isDebugEnabled()) { + log.debug("Execute Update SQL : {}", this.updateStatementSql); + } + + try { + int[] affects = jdbcTemplate.batchUpdate(this.updateStatementSql, datas, this.updateArgsType); + int affectCount = 0; + for (int i : affects) { + affectCount += i; + } + + transactionManager.commit(status); + return affectCount; + } catch (TransactionException e) { + transactionManager.rollback(status); + throw e; + } catch (Exception e) { + transactionManager.rollback(status); + throw e; + } + } + + @Override + public long executeDelete(List records) { + List datas = new LinkedList<>(); + for (Object[] r : records) { + Object[] nr = new Object[this.pksOrders.size()]; + for (int i = 0; i < this.pksOrders.size(); ++i) { + String pk = this.pksOrders.get(i); + int index = this.fieldOrders.indexOf(pk); + nr[i] = r[index]; + } + + datas.add(nr); + } + + TransactionStatus status = transactionManager.getTransaction(defination); + if (log.isDebugEnabled()) { + log.debug("Execute Delete SQL : {}", this.deleteStatementSql); + } + + try { + int[] affects = jdbcTemplate.batchUpdate(this.deleteStatementSql, datas, this.deleteArgsType); + int affectCount = 0; + for (int i : affects) { + affectCount += i; + } + + transactionManager.commit(status); + return affectCount; + } catch (TransactionException e) { + transactionManager.rollback(status); + throw e; + } catch (Exception e) { + transactionManager.rollback(status); + throw e; + } finally { + datas.clear(); + } + } } diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/DatabaseSynchronizeFactory.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/DatabaseSynchronizeFactory.java index 25cef0b9..a7be543f 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/DatabaseSynchronizeFactory.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/DatabaseSynchronizeFactory.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch; @@ -21,54 +21,44 @@ import com.gitee.dbswitch.dbsynch.mysql.MySqlDatabaseSynchImpl; import com.gitee.dbswitch.dbsynch.oracle.OracleDatabaseSynchImpl; import com.gitee.dbswitch.dbsynch.pgsql.GreenplumDatabaseSynchImpl; import com.gitee.dbswitch.dbsynch.pgsql.PostgresqlDatabaseSynchImpl; -import java.lang.reflect.Constructor; +import java.util.function.Function; /** * 数据库同步器构造工厂类 - * - * @author tang * + * @author tang */ public final class DatabaseSynchronizeFactory { - private static final Map DATABASE_SYNCH_MAPPER = new HashMap() { + private static final Map> DATABASE_SYNCH_MAPPER = new HashMap>() { - private static final long serialVersionUID = -2359773637275934408L; + private static final long serialVersionUID = -2359773637275934408L; - { - put("MYSQL", MySqlDatabaseSynchImpl.class.getName()); - put("ORACLE", OracleDatabaseSynchImpl.class.getName()); - put("SQLSERVER", SqlServerDatabaseSynchImpl.class.getName()); - put("POSTGRESQL", PostgresqlDatabaseSynchImpl.class.getName()); - put("GREENPLUM", GreenplumDatabaseSynchImpl.class.getName()); - put("DB2",DB2DatabaseSynchImpl.class.getName()); - put("DM",DmDatabaseSynchImpl.class.getName()); - put("KINGBASE",KingbaseDatabaseSynchImpl.class.getName()); - } - }; + { + put("MYSQL", MySqlDatabaseSynchImpl::new); + put("ORACLE", OracleDatabaseSynchImpl::new); + put("SQLSERVER", SqlServerDatabaseSynchImpl::new); + put("POSTGRESQL", PostgresqlDatabaseSynchImpl::new); + put("GREENPLUM", GreenplumDatabaseSynchImpl::new); + put("DB2", DB2DatabaseSynchImpl::new); + put("DM", DmDatabaseSynchImpl::new); + put("KINGBASE", KingbaseDatabaseSynchImpl::new); + } + }; - /** - * 获取指定数据源的同步器 - * - * @param dataSource 数据源 - * @return 同步器对象 - */ - public static AbstractDatabaseSynchronize createDatabaseWriter(DataSource dataSource) { - String type = DatabaseAwareUtils.getDatabaseNameByDataSource(dataSource).toUpperCase(); + /** + * 获取指定数据源的同步器 + * + * @param dataSource 数据源 + * @return 同步器对象 + */ + public static IDatabaseSynchronize createDatabaseWriter(DataSource dataSource) { + String type = DatabaseAwareUtils.getDatabaseNameByDataSource(dataSource).toUpperCase(); - if (DATABASE_SYNCH_MAPPER.containsKey(type)) { - String className = DATABASE_SYNCH_MAPPER.get(type); - try { - Class[] paramTypes = { DataSource.class }; - Object[] paramValues = { dataSource }; - Class clas = Class.forName(className); - Constructor cons = clas.getConstructor(paramTypes); - return (AbstractDatabaseSynchronize) cons.newInstance(paramValues); - } catch (Exception e) { - throw new RuntimeException(e); - } - } + if (!DATABASE_SYNCH_MAPPER.containsKey(type)) { + throw new RuntimeException(String.format("[dbsynch] Unkown Supported database type (%s)", type)); + } - throw new RuntimeException(String.format("[dbsynch] Unkown Supported database type (%s)", type)); - } + return DATABASE_SYNCH_MAPPER.get(type).apply(dataSource); + } } diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/IDatabaseSynchronize.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/IDatabaseSynchronize.java index cfa3f803..c6a9ce24 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/IDatabaseSynchronize.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/IDatabaseSynchronize.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch; diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/db2/DB2DatabaseSynchImpl.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/db2/DB2DatabaseSynchImpl.java index 49b9b896..f5e0943d 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/db2/DB2DatabaseSynchImpl.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/db2/DB2DatabaseSynchImpl.java @@ -4,73 +4,64 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch.db2; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; import com.gitee.dbswitch.dbsynch.AbstractDatabaseSynchronize; import com.gitee.dbswitch.dbsynch.IDatabaseSynchronize; /** - * DB2数据库实现类 - * - * @author tang + * DB2数据库DML同步实现类 * + * @author tang */ public class DB2DatabaseSynchImpl extends AbstractDatabaseSynchronize implements IDatabaseSynchronize { - public DB2DatabaseSynchImpl(DataSource ds) { - super(ds); - } + public DB2DatabaseSynchImpl(DataSource ds) { + super(ds); + } - @Override - public String getColumMetaDataSql(String schemaName, String tableName) { - return String.format("SELECT * FROM \"%s\".\"%s\" WHERE 1=2", schemaName, tableName); - } + @Override + public String getColumnMetaDataSql(String schemaName, String tableName) { + return String.format("SELECT * FROM \"%s\".\"%s\" WHERE 1=2", schemaName, tableName); + } - @Override - public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } + @Override + public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); + return String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, + StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); + } - return String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, - StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); - } - - @Override - public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, - List pks) { - List uf = new ArrayList(); - for (String field : fieldNames) { - if (!pks.contains(field)) { - uf.add(String.format("\"%s\"=?", field)); - } - } + @Override + public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, List pks) { + List uf = fieldNames.stream() + .filter(field -> !pks.contains(field)) + .map(field -> String.format("\"%s\"=?", field)) + .collect(Collectors.toList()); - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("\"%s\"=?", pk)); - } + List uw = pks.stream() + .map(pk -> String.format("\"%s\"=?", pk)) + .collect(Collectors.toList()); - return String.format("UPDATE \"%s\".\"%s\" SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), - StringUtils.join(uw, " AND ")); - } + return String.format("UPDATE \"%s\".\"%s\" SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), + StringUtils.join(uw, " AND ")); + } - @Override - public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("\"%s\"=?", pk)); - } + @Override + public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { + List uw = pks.stream() + .map(pk -> String.format("\"%s\"=?", pk)) + .collect(Collectors.toList()); - return String.format("DELETE FROM \"%s\".\"%s\" WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); - } + return String.format("DELETE FROM \"%s\".\"%s\" WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); + } } diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/dm/DmDatabaseSynchImpl.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/dm/DmDatabaseSynchImpl.java index 55a62f40..e47a0d75 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/dm/DmDatabaseSynchImpl.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/dm/DmDatabaseSynchImpl.java @@ -4,15 +4,19 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch.dm; import javax.sql.DataSource; - import com.gitee.dbswitch.dbsynch.oracle.OracleDatabaseSynchImpl; +/** + * DM数据库DML同步实现类 + * + * @author tang + */ public class DmDatabaseSynchImpl extends OracleDatabaseSynchImpl { public DmDatabaseSynchImpl(DataSource ds) { diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/kingbase/KingbaseDatabaseSynchImpl.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/kingbase/KingbaseDatabaseSynchImpl.java index 8bcb6bba..bddae82e 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/kingbase/KingbaseDatabaseSynchImpl.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/kingbase/KingbaseDatabaseSynchImpl.java @@ -4,15 +4,20 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch.kingbase; import javax.sql.DataSource; - import com.gitee.dbswitch.dbsynch.pgsql.PostgresqlDatabaseSynchImpl; +/** + * kingbase8数据库DML同步实现类 + * + * @author tang + * + */ public class KingbaseDatabaseSynchImpl extends PostgresqlDatabaseSynchImpl { public KingbaseDatabaseSynchImpl(DataSource ds) { diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/mssql/SqlServerDatabaseSynchImpl.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/mssql/SqlServerDatabaseSynchImpl.java index 3c5323c2..b794fd30 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/mssql/SqlServerDatabaseSynchImpl.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/mssql/SqlServerDatabaseSynchImpl.java @@ -4,73 +4,64 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch.mssql; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; import com.gitee.dbswitch.dbsynch.AbstractDatabaseSynchronize; import com.gitee.dbswitch.dbsynch.IDatabaseSynchronize; /** - * SQLServer数据库实现类 - * - * @author tang + * SQLServer数据库DML同步实现类 * + * @author tang */ public class SqlServerDatabaseSynchImpl extends AbstractDatabaseSynchronize implements IDatabaseSynchronize { - public SqlServerDatabaseSynchImpl(DataSource ds) { - super(ds); - } + public SqlServerDatabaseSynchImpl(DataSource ds) { + super(ds); + } - @Override - public String getColumMetaDataSql(String schemaName, String tableName) { - return String.format("SELECT * FROM [%s].[%s] WHERE 1=2", schemaName, tableName); - } + @Override + public String getColumnMetaDataSql(String schemaName, String tableName) { + return String.format("SELECT * FROM [%s].[%s] WHERE 1=2", schemaName, tableName); + } - @Override - public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } + @Override + public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); + return String.format("INSERT INTO [%s].[%s] ( [%s] ) VALUES ( %s )", schemaName, tableName, + StringUtils.join(fieldNames, "],["), StringUtils.join(placeHolders, ",")); + } - return String.format("INSERT INTO [%s].[%s] ( [%s] ) VALUES ( %s )", schemaName, tableName, - StringUtils.join(fieldNames, "],["), StringUtils.join(placeHolders, ",")); - } + @Override + public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, List pks) { + List uf = fieldNames.stream() + .filter(field -> !pks.contains(field)) + .map(field -> String.format("[%s]=?", field)) + .collect(Collectors.toList()); - @Override - public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, - List pks) { - List uf = new ArrayList(); - for (String field : fieldNames) { - if (!pks.contains(field)) { - uf.add(String.format("[%s]=?", field)); - } - } + List uw = pks.stream() + .map(pk -> String.format("[%s]=?", pk)) + .collect(Collectors.toList()); - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("[%s]=?", pk)); - } + return String.format("UPDATE [%s].[%s] SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), + StringUtils.join(uw, " AND ")); + } - return String.format("UPDATE [%s].[%s] SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), - StringUtils.join(uw, " AND ")); - } + @Override + public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { + List uw = pks.stream() + .map(pk -> String.format("[%s]=?", pk)) + .collect(Collectors.toList()); - @Override - public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("[%s]=?", pk)); - } - - return String.format("DELETE FROM [%s].[%s] WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); - } + return String.format("DELETE FROM [%s].[%s] WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); + } } diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/mysql/MySqlDatabaseSynchImpl.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/mysql/MySqlDatabaseSynchImpl.java index b0211755..140d585a 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/mysql/MySqlDatabaseSynchImpl.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/mysql/MySqlDatabaseSynchImpl.java @@ -4,73 +4,64 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch.mysql; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; import com.gitee.dbswitch.dbsynch.AbstractDatabaseSynchronize; import com.gitee.dbswitch.dbsynch.IDatabaseSynchronize; /** - * MySQL数据库实现类 - * - * @author tang + * MySQL数据库DML同步实现类 * + * @author tang */ public class MySqlDatabaseSynchImpl extends AbstractDatabaseSynchronize implements IDatabaseSynchronize { - public MySqlDatabaseSynchImpl(DataSource ds) { - super(ds); - } + public MySqlDatabaseSynchImpl(DataSource ds) { + super(ds); + } - @Override - public String getColumMetaDataSql(String schemaName, String tableName) { - return String.format("SELECT * FROM `%s`.`%s` WHERE 1=2", schemaName, tableName); - } + @Override + public String getColumnMetaDataSql(String schemaName, String tableName) { + return String.format("SELECT * FROM `%s`.`%s` WHERE 1=2", schemaName, tableName); + } - @Override - public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } + @Override + public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); + return String.format("INSERT INTO `%s`.`%s` ( `%s` ) VALUES ( %s )", schemaName, tableName, + StringUtils.join(fieldNames, "`,`"), StringUtils.join(placeHolders, ",")); + } - return String.format("INSERT INTO `%s`.`%s` ( `%s` ) VALUES ( %s )", schemaName, tableName, - StringUtils.join(fieldNames, "`,`"), StringUtils.join(placeHolders, ",")); - } - - @Override - public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, - List pks) { - List uf = new ArrayList(); - for (String field : fieldNames) { - if (!pks.contains(field)) { - uf.add(String.format("`%s`=?", field)); - } - } + @Override + public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, List pks) { + List uf = fieldNames.stream() + .filter(field -> !pks.contains(field)) + .map(field -> String.format("`%s`=?", field)) + .collect(Collectors.toList()); - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("`%s`=?", pk)); - } + List uw = pks.stream() + .map(pk -> String.format("`%s`=?", pk)) + .collect(Collectors.toList()); - return String.format("UPDATE `%s`.`%s` SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), - StringUtils.join(uw, " AND ")); - } + return String.format("UPDATE `%s`.`%s` SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), + StringUtils.join(uw, " AND ")); + } - @Override - public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("`%s`=?", pk)); - } + @Override + public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { + List uw = pks.stream() + .map(pk -> String.format("`%s`=?", pk)) + .collect(Collectors.toList()); - return String.format("DELETE FROM `%s`.`%s` WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); - } + return String.format("DELETE FROM `%s`.`%s` WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); + } } diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/oracle/OracleDatabaseSynchImpl.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/oracle/OracleDatabaseSynchImpl.java index 24af1578..637209f1 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/oracle/OracleDatabaseSynchImpl.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/oracle/OracleDatabaseSynchImpl.java @@ -4,73 +4,64 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch.oracle; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; import com.gitee.dbswitch.dbsynch.AbstractDatabaseSynchronize; import com.gitee.dbswitch.dbsynch.IDatabaseSynchronize; /** - * Oracle数据库实现类 - * - * @author tang + * Oracle数据库DML同步实现类 * + * @author tang */ public class OracleDatabaseSynchImpl extends AbstractDatabaseSynchronize implements IDatabaseSynchronize { - public OracleDatabaseSynchImpl(DataSource ds) { - super(ds); - } + public OracleDatabaseSynchImpl(DataSource ds) { + super(ds); + } - @Override - public String getColumMetaDataSql(String schemaName, String tableName) { - return String.format("SELECT * FROM \"%s\".\"%s\" WHERE 1=2", schemaName, tableName); - } + @Override + public String getColumnMetaDataSql(String schemaName, String tableName) { + return String.format("SELECT * FROM \"%s\".\"%s\" WHERE 1=2", schemaName, tableName); + } - @Override - public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } + @Override + public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); + return String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, + StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); + } - return String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, - StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); - } - - @Override - public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, - List pks) { - List uf = new ArrayList(); - for (String field : fieldNames) { - if (!pks.contains(field)) { - uf.add(String.format("\"%s\"=?", field)); - } - } + @Override + public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, List pks) { + List uf = fieldNames.stream() + .filter(field -> !pks.contains(field)) + .map(field -> String.format("\"%s\"=?", field)) + .collect(Collectors.toList()); - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("\"%s\"=?", pk)); - } + List uw = pks.stream() + .map(pk -> String.format("\"%s\"=?", pk)) + .collect(Collectors.toList()); - return String.format("UPDATE \"%s\".\"%s\" SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), - StringUtils.join(uw, " AND ")); - } + return String.format("UPDATE \"%s\".\"%s\" SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), + StringUtils.join(uw, " AND ")); + } - @Override - public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("\"%s\"=?", pk)); - } + @Override + public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { + List uw = pks.stream() + .map(pk -> String.format("\"%s\"=?", pk)) + .collect(Collectors.toList()); - return String.format("DELETE FROM \"%s\".\"%s\" WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); - } + return String.format("DELETE FROM \"%s\".\"%s\" WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); + } } diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/pgsql/GreenplumDatabaseSynchImpl.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/pgsql/GreenplumDatabaseSynchImpl.java index 4d039d50..6ee05f94 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/pgsql/GreenplumDatabaseSynchImpl.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/pgsql/GreenplumDatabaseSynchImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch.pgsql; @@ -13,7 +13,7 @@ import javax.sql.DataSource; import com.gitee.dbswitch.dbsynch.IDatabaseSynchronize; /** - * Greenplum数据库实现类 + * Greenplum数据库DML同步实现类 * * @author tang * diff --git a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/pgsql/PostgresqlDatabaseSynchImpl.java b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/pgsql/PostgresqlDatabaseSynchImpl.java index e6e7ccfa..ab36c818 100644 --- a/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/pgsql/PostgresqlDatabaseSynchImpl.java +++ b/dbswitch-dbsynch/src/main/java/com/gitee/dbswitch/dbsynch/pgsql/PostgresqlDatabaseSynchImpl.java @@ -4,73 +4,64 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbsynch.pgsql; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; +import java.util.stream.Collectors; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; import com.gitee.dbswitch.dbsynch.AbstractDatabaseSynchronize; import com.gitee.dbswitch.dbsynch.IDatabaseSynchronize; /** - * PostgreSQL数据库实现类 - * - * @author tang + * PostgreSQL数据库DML同步实现类 * + * @author tang */ public class PostgresqlDatabaseSynchImpl extends AbstractDatabaseSynchronize implements IDatabaseSynchronize { - public PostgresqlDatabaseSynchImpl(DataSource ds) { - super(ds); - } + public PostgresqlDatabaseSynchImpl(DataSource ds) { + super(ds); + } - @Override - public String getColumMetaDataSql(String schemaName, String tableName) { - return String.format("SELECT * FROM \"%s\".\"%s\" WHERE 1=2", schemaName, tableName); - } - - @Override - public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } + @Override + public String getColumnMetaDataSql(String schemaName, String tableName) { + return String.format("SELECT * FROM \"%s\".\"%s\" WHERE 1=2", schemaName, tableName); + } - return String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, - StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); - } + @Override + public String getInsertPrepareStatementSql(String schemaName, String tableName, List fieldNames) { + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); + return String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, + StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); + } - @Override - public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, - List pks) { - List uf = new ArrayList(); - for (String field : fieldNames) { - if (!pks.contains(field)) { - uf.add(String.format("\"%s\"=?", field)); - } - } + @Override + public String getUpdatePrepareStatementSql(String schemaName, String tableName, List fieldNames, List pks) { + List uf = fieldNames.stream() + .filter(field -> !pks.contains(field)) + .map(field -> String.format("\"%s\"=?", field)) + .collect(Collectors.toList()); - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("\"%s\"=?", pk)); - } + List uw = pks.stream() + .map(pk -> String.format("\"%s\"=?", pk)) + .collect(Collectors.toList()); - return String.format("UPDATE \"%s\".\"%s\" SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), - StringUtils.join(uw, " AND ")); - } + return String.format("UPDATE \"%s\".\"%s\" SET %s WHERE %s", schemaName, tableName, StringUtils.join(uf, " , "), + StringUtils.join(uw, " AND ")); + } - @Override - public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { - List uw = new ArrayList(); - for (String pk : pks) { - uw.add(String.format("\"%s\"=?", pk)); - } + @Override + public String getDeletePrepareStatementSql(String schemaName, String tableName, List pks) { + List uw = pks.stream() + .map(pk -> String.format("\"%s\"=?", pk)) + .collect(Collectors.toList()); - return String.format("DELETE FROM \"%s\".\"%s\" WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); - } + return String.format("DELETE FROM \"%s\".\"%s\" WHERE %s ", schemaName, tableName, StringUtils.join(uw, " AND ")); + } } diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/AbstractDatabaseWriter.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/AbstractDatabaseWriter.java index d8646ba6..e6def020 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/AbstractDatabaseWriter.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/AbstractDatabaseWriter.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter; diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/DatabaseWriterFactory.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/DatabaseWriterFactory.java index a2e085d3..d2cb77a5 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/DatabaseWriterFactory.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/DatabaseWriterFactory.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter; @@ -12,8 +12,8 @@ package com.gitee.dbswitch.dbwriter; import java.util.Map; import java.util.HashMap; import javax.sql.DataSource; +import java.util.function.Function; import com.gitee.dbswitch.dbcommon.util.DatabaseAwareUtils; -import java.lang.reflect.Constructor; /** * 数据库写入器构造工厂类 @@ -23,20 +23,20 @@ import java.lang.reflect.Constructor; */ public class DatabaseWriterFactory { - private static final Map DATABASE_WRITER_MAPPER = new HashMap() { + private static final Map> DATABASE_WRITER_MAPPER = new HashMap>() { private static final long serialVersionUID = 3365136872693503697L; { - put("MYSQL", "com.gitee.dbswitch.dbwriter.mysql.MySqlWriterImpl"); - put("ORACLE", "com.gitee.dbswitch.dbwriter.oracle.OracleWriterImpl"); - put("SQLSERVER", "com.gitee.dbswitch.dbwriter.mssql.SqlServerWriterImpl"); - put("POSTGRESQL", "com.gitee.dbswitch.dbwriter.gpdb.GreenplumCopyWriterImpl"); - put("GREENPLUM", "com.gitee.dbswitch.dbwriter.gpdb.GreenplumCopyWriterImpl"); - put("DB2", "com.gitee.dbswitch.dbwriter.db2.DB2WriterImpl"); - put("DM", "com.gitee.dbswitch.dbwriter.dm.DmWriterImpl"); + put("MYSQL", com.gitee.dbswitch.dbwriter.mysql.MySqlWriterImpl::new); + put("ORACLE", com.gitee.dbswitch.dbwriter.oracle.OracleWriterImpl::new); + put("SQLSERVER", com.gitee.dbswitch.dbwriter.mssql.SqlServerWriterImpl::new); + put("POSTGRESQL", com.gitee.dbswitch.dbwriter.gpdb.GreenplumCopyWriterImpl::new); + put("GREENPLUM", com.gitee.dbswitch.dbwriter.gpdb.GreenplumCopyWriterImpl::new); + put("DB2", com.gitee.dbswitch.dbwriter.db2.DB2WriterImpl::new); + put("DM", com.gitee.dbswitch.dbwriter.dm.DmWriterImpl::new); //对于kingbase当前只能使用insert模式 - put("KINGBASE", "com.gitee.dbswitch.dbwriter.kingbase.KingbaseInsertWriterImpl"); + put("KINGBASE", com.gitee.dbswitch.dbwriter.kingbase.KingbaseInsertWriterImpl::new); } }; @@ -46,7 +46,7 @@ public class DatabaseWriterFactory { * @param dataSource 连接池数据源 * @return 写入器对象 */ - public static AbstractDatabaseWriter createDatabaseWriter(DataSource dataSource) { + public static IDatabaseWriter createDatabaseWriter(DataSource dataSource) { return DatabaseWriterFactory.createDatabaseWriter(dataSource, false); } @@ -57,33 +57,19 @@ public class DatabaseWriterFactory { * @param insert 对于GP/GP数据库来说是否使用insert引擎写入 * @return 写入器对象 */ - public static AbstractDatabaseWriter createDatabaseWriter(DataSource dataSource, boolean insert) { + public static IDatabaseWriter createDatabaseWriter(DataSource dataSource, boolean insert) { String type = DatabaseAwareUtils.getDatabaseNameByDataSource(dataSource).toUpperCase(); if (insert) { if ("POSTGRESQL".equalsIgnoreCase(type) || "GREENPLUM".equalsIgnoreCase(type)) { return new com.gitee.dbswitch.dbwriter.gpdb.GreenplumInsertWriterImpl(dataSource); } - - if ("KINGBASE".equalsIgnoreCase(type)) { - return new com.gitee.dbswitch.dbwriter.kingbase.KingbaseInsertWriterImpl(dataSource); - } } - if (DATABASE_WRITER_MAPPER.containsKey(type.trim())) { - String className = DATABASE_WRITER_MAPPER.get(type); - try { - Class[] paraTypes = { DataSource.class }; - Object[] paraValues = { dataSource }; - Class clas = Class.forName(className); - Constructor cons = clas.getConstructor(paraTypes); - AbstractDatabaseWriter process = (AbstractDatabaseWriter) cons.newInstance(paraValues); - return process; - } catch (Exception e) { - throw new RuntimeException(e); - } + if (!DATABASE_WRITER_MAPPER.containsKey(type.trim())) { + throw new RuntimeException(String.format("[dbwrite] Unkown Supported database type (%s)", type)); } - throw new RuntimeException(String.format("[dbwrite] Unkown Supported database type (%s)", type)); + return DATABASE_WRITER_MAPPER.get(type.trim()).apply(dataSource); } } diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/IDatabaseWriter.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/IDatabaseWriter.java index d2565b8b..f47c6e9b 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/IDatabaseWriter.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/IDatabaseWriter.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter; diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/db2/DB2WriterImpl.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/db2/DB2WriterImpl.java index 6abecc38..9d2dc170 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/db2/DB2WriterImpl.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/db2/DB2WriterImpl.java @@ -4,12 +4,12 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter.db2; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; import javax.sql.DataSource; @@ -38,13 +38,11 @@ public class DB2WriterImpl extends AbstractDatabaseWriter implements IDatabaseWr @Override public long write(List fieldNames, List recordValues) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } - String schemaName = Objects.requireNonNull(this.schemaName, "schema-name名称为空,不合法!"); String tableName = Objects.requireNonNull(this.tableName, "table-name名称为空,不合法!"); + + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); + String sqlInsert = String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/dm/DmWriterImpl.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/dm/DmWriterImpl.java index 208b082e..414a20ec 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/dm/DmWriterImpl.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/dm/DmWriterImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter.dm; @@ -13,6 +13,12 @@ import javax.sql.DataSource; import com.gitee.dbswitch.dbwriter.oracle.OracleWriterImpl; import com.gitee.dbswitch.dbwriter.IDatabaseWriter; +/** + * DM数据库写入实现类 + * + * @author tang + * + */ public class DmWriterImpl extends OracleWriterImpl implements IDatabaseWriter { public DmWriterImpl(DataSource dataSource) { diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/gpdb/GreenplumCopyWriterImpl.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/gpdb/GreenplumCopyWriterImpl.java index adb704f4..90bd769d 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/gpdb/GreenplumCopyWriterImpl.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/gpdb/GreenplumCopyWriterImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter.gpdb; @@ -29,6 +29,7 @@ import java.util.Map; import java.util.Objects; import java.util.function.Consumer; import javax.sql.DataSource; + import org.springframework.dao.DataAccessException; import org.springframework.jdbc.core.ConnectionCallback; import org.springframework.jdbc.support.JdbcUtils; @@ -41,1290 +42,1285 @@ import lombok.extern.slf4j.Slf4j; /** * Greenplum数据库Copy写入实现类 - * - * @author tang * + * @author tang */ @Slf4j public class GreenplumCopyWriterImpl extends AbstractDatabaseWriter implements IDatabaseWriter { - protected Map columnType; - - public GreenplumCopyWriterImpl(DataSource dataSource) { - super(dataSource); - - this.columnType = null; - } - - @Override - public void prepareWrite(String schemaName, String tableName) { - String sql = String.format("SELECT * from \"%s\".\"%s\" where 1=2", schemaName, tableName); - Map columnMetaData = new HashMap(); - Boolean ret = this.jdbcTemplate.execute(new ConnectionCallback() { - - @Override - public Boolean doInConnection(Connection conn) throws SQLException, DataAccessException { - Statement stmt = null; - ResultSet rs = null; - try { - stmt = conn.createStatement(); - rs = stmt.executeQuery(sql); - ResultSetMetaData rsMetaData = rs.getMetaData(); - for (int i = 0, len = rsMetaData.getColumnCount(); i < len; i++) { - columnMetaData.put(rsMetaData.getColumnName(i + 1), rsMetaData.getColumnType(i + 1)); - } - - return true; - } catch (Exception e) { - throw new RuntimeException( - String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName), e); - } finally { - JdbcUtils.closeResultSet(rs); - JdbcUtils.closeStatement(stmt); - } - } - }); - - if (ret) { - this.schemaName = Objects.requireNonNull(schemaName, "schema-name名称为空,不合法!"); - this.tableName = Objects.requireNonNull(tableName, "table-name名称为空,不合法!"); - this.columnType = Objects.requireNonNull(columnMetaData); - - if (this.columnType.isEmpty()) { - throw new RuntimeException( - String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName)); - } - } else { - throw new RuntimeException("内部代码出现错误,请开发人员排查!"); - } - } - - @Override - public long write(List fieldNames, List recordValues) { - if (null == this.columnType || this.columnType.isEmpty()) { - throw new RuntimeException("请先调用prepareWrite()函数,或者出现内部代码集成调用错误!"); - } - - if (fieldNames.isEmpty()) { - throw new IllegalArgumentException("第一个参数[fieldNames]为空,无效!"); - } - - if (recordValues.isEmpty()) { - return 0; - } - - String[] columnNames = new String[fieldNames.size()]; - for (int i = 0; i < fieldNames.size(); ++i) { - String s = fieldNames.get(i); - if (!this.columnType.containsKey(s)) { - throw new RuntimeException(String.format("表%s.%s 中不存在字段名为%s的字段,请检查参数传入!", schemaName, tableName, s)); - } - - columnNames[i] = s; - } - - String schemaName = Objects.requireNonNull(this.schemaName, "schema-name名称为空,不合法!"); - String tableName = Objects.requireNonNull(this.tableName, "table-name名称为空,不合法!"); - SimpleRowWriter.Table table = new SimpleRowWriter.Table(schemaName, tableName, columnNames); - - Connection connection = null; - try { - connection = dataSource.getConnection(); - } catch (SQLException e) { - throw new RuntimeException(e); - } - - try (SimpleRowWriter pgwriter = new SimpleRowWriter(table, PostgreSqlUtils.getPGConnection(connection), - true);) { - pgwriter.enableNullCharacterHandler(); - - long count = recordValues.size(); - for (Object[] objects : recordValues) { - if (fieldNames.size() != objects.length) { - throw new RuntimeException( - String.format("传入的参数有误,字段列数%d与记录中的值个数%d不相符合", fieldNames.size(), objects.length)); - } - - /** - * 数据类型转换参考 - *

- * 1. spring-jdbc: {@code org.springframework.jdbc.core.StatementCreatorUtils} - *

- *

- * 2. postgresql-driver: {@code org.postgresql.jdbc.PgPreparedStatement} - *

- */ - pgwriter.startRow(new Consumer() { - - @Override - public void accept(SimpleRow row) { - for (int i = 0; i < objects.length; ++i) { - String fieldName = fieldNames.get(i); - Object fieldValue = objects[i]; - Integer fieldType = columnType.get(fieldName); - switch (fieldType) { - case Types.CHAR: - case Types.NCHAR: - case Types.VARCHAR: - case Types.LONGVARCHAR: - case Types.NVARCHAR: - case Types.LONGNVARCHAR: - if (null == fieldValue) { - row.setVarChar(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { - row.setVarChar(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { - row.setVarChar(i, null); - } else { - String val = castToString(fieldValue); - if (null == val) { - throw new RuntimeException(String.format( - "表[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.String/java.sql.Clob,而实际的数据类型为%s", - schemaName, tableName, fieldName, fieldValue.getClass().getName())); - } - - row.setVarChar(i, val); - } - break; - case Types.CLOB: - case Types.NCLOB: - if (null == fieldValue) { - row.setText(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { - row.setText(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { - row.setText(i, null); - } else { - String val = castToString(fieldValue); - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.String/java.sql.Clob,而实际的数据类型为%s", - schemaName, tableName, fieldName, fieldValue.getClass().getName())); - } - - row.setText(i, val); - } - break; - case Types.TINYINT: - if (null == fieldValue) { - row.setByte(i, null); - } else { - Byte val = null; - try { - val = castToByte(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转错误,应该为java.lang.Byte,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - - row.setByte(i, val); - } - break; - case Types.SMALLINT: - if (null == fieldValue) { - row.setShort(i, null); - } else { - Short val = null; - try { - val = castToShort(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Short,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - - row.setShort(i, val); - } - break; - case Types.INTEGER: - if (null == fieldValue) { - row.setInteger(i, null); - } else { - Integer val = null; - try { - val = castToInteger(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Integer,而实际的数据类型为%s", - schemaName, tableName, fieldName, fieldValue.getClass().getName())); - } - - row.setInteger(i, val); - } - break; - case Types.BIGINT: - if (null == fieldValue) { - row.setLong(i, null); - } else { - Long val = null; - try { - val = castToLong(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Long,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - - row.setLong(i, val); - } - break; - case Types.NUMERIC: - case Types.DECIMAL: - if (null == fieldValue) { - row.setNumeric(i, null); - } else { - Number val = null; - try { - val = castToNumeric(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Number,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - - row.setNumeric(i, val); - } - break; - case Types.FLOAT: - case Types.REAL: - if (null == fieldValue) { - row.setFloat(i, null); - } else { - Float val = null; - try { - val = castToFloat(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Float,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - - row.setFloat(i, val); - } - break; - case Types.DOUBLE: - if (null == fieldValue) { - row.setDouble(i, null); - } else { - Double val = null; - try { - val = castToDouble(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Double,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - row.setDouble(i, val); - } - break; - case Types.BOOLEAN: - case Types.BIT: - if (null == fieldValue) { - row.setBoolean(i, null); - } else { - Boolean val = null; - try { - val = castToBoolean(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型错误,应该为java.lang.Boolean,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - row.setBoolean(i, val); - } - break; - case Types.TIME: - if (null == fieldValue) { - row.setTime(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { - row.setTime(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { - row.setTime(i, null); - } else { - LocalTime val = null; - try { - val = castToLocalTime(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.sql.Time,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - row.setTime(i, val); - } - break; - case Types.DATE: - if (null == fieldValue) { - row.setDate(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { - row.setDate(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { - row.setDate(i, null); - } else { - LocalDate val = null; - try { - val = castToLocalDate(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.sql.Date,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - row.setDate(i, val); - } - break; - case Types.TIMESTAMP: - if (null == fieldValue) { - row.setTimeStamp(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { - row.setTimeStamp(i, null); - } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { - row.setTimeStamp(i, null); - } else { - LocalDateTime val = null; - try { - val = castToLocalDateTime(fieldValue); - } catch (RuntimeException e) { - throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", - schemaName, tableName, fieldName, e.getMessage())); - } - - if (null == val) { - throw new RuntimeException(String.format( - "表名[%s.%s]的字段名[%s]数据类型错误,应该为java.sql.Timestamp,而实际的数据类型为%s", schemaName, - tableName, fieldName, fieldValue.getClass().getName())); - } - - row.setTimeStamp(i, val); - } - break; - case Types.BINARY: - case Types.VARBINARY: - case Types.BLOB: - case Types.LONGVARBINARY: - if (null == fieldValue) { - row.setByteArray(i, null); - } else { - row.setByteArray(i, castToByteArray(fieldValue)); - } - break; - case Types.NULL: - case Types.OTHER: - if (null == fieldValue) { - row.setText(i, null); - } else { - row.setText(i, fieldValue.toString()); - } - break; - default: - throw new RuntimeException(String.format("不支持的数据库字段类型,表名[%s.%s] 字段名[%s].", schemaName, - tableName, fieldName)); - } - } - } - }); - } - - return count; - } catch (SQLException e) { - throw new RuntimeException(e); - } finally { - JdbcUtils.closeConnection(connection); - } - - } - - /** - * 将java.sql.Clob类型转换为java.lang.String类型 - * - * @param clob java.sql.Clob类型对象 - * @return java.lang.String类型数据 - */ - private String clob2Str(java.sql.Clob clob) { - if (null == clob) { - return null; - } - - java.io.Reader is = null; - java.io.BufferedReader reader = null; - try { - is = clob.getCharacterStream(); - reader = new java.io.BufferedReader(is); - String line = reader.readLine(); - StringBuilder sb = new StringBuilder(); - while (line != null) { - sb.append(line); - line = reader.readLine(); - } - return sb.toString(); - } catch (SQLException | java.io.IOException e) { - throw new RuntimeException(e); - } finally { - try { - if (null != reader) { - reader.close(); - } - if (null != is) { - is.close(); - } - } catch (Exception ex) { - - } - } - } - - /** - * 将java.sql.Blob类型转换为byte数组 - * - * @param clob java.sql.Blob类型对象 - * @return byte数组 - */ - private byte[] blob2Bytes(java.sql.Blob blob) { - if (null == blob) { - return null; - } - - java.io.BufferedInputStream bufferedInputStream = null; - try { - bufferedInputStream = new java.io.BufferedInputStream(blob.getBinaryStream()); - byte[] bytes = new byte[(int) blob.length()]; - int len = bytes.length; - int offset = 0; - int read = 0; - while (offset < len && (read = bufferedInputStream.read(bytes, offset, len - offset)) >= 0) { - offset += read; - } - return bytes; - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - try { - bufferedInputStream.close(); - } catch (Exception e) { - } - } - } - - /** - * 将Object对象转换为字节数组 - * - * @param obj 对象 - * @return 字节数组 - */ - private byte[] toByteArray(Object obj) { - if (null == obj) { - return null; - } - - ByteArrayOutputStream bos = null; - ObjectOutputStream oos = null; - try { - bos = new ByteArrayOutputStream(); - oos = new ObjectOutputStream(bos); - oos.writeObject(obj); - oos.flush(); - return bos.toByteArray(); - } catch (Exception e) { - throw new RuntimeException(e); - } finally { - try { - if (null != oos) { - oos.close(); - } - - if (null != bos) { - bos.close(); - } - } catch (Exception e) { - } - } - } - - /** - * 将任意类型转换为java.lang.String类型 - * - * @param in 任意类型的对象实例 - * @return java.lang.String类型 - */ - private String castToString(final Object in) { - if (in instanceof java.lang.Character) { - return in.toString(); - } else if (in instanceof java.lang.String) { - return in.toString(); - } else if (in instanceof java.lang.Character) { - return in.toString(); - } else if (in instanceof java.sql.Clob) { - return clob2Str((java.sql.Clob) in); - } else if (in instanceof java.lang.Number) { - return in.toString(); - } else if (in instanceof java.sql.RowId) { - return in.toString(); - } else if (in instanceof java.lang.Boolean) { - return in.toString(); - } else if (in instanceof java.util.Date) { - return in.toString(); - } else if (in instanceof java.time.LocalDate) { - return in.toString(); - } else if (in instanceof java.time.LocalTime) { - return in.toString(); - } else if (in instanceof java.time.LocalDateTime) { - return in.toString(); - } else if (in instanceof java.time.OffsetDateTime) { - return in.toString(); - } else if (in instanceof java.util.UUID) { - return in.toString(); - } else if (in instanceof org.postgresql.util.PGobject) { - return in.toString(); - } else if (in instanceof org.postgresql.jdbc.PgSQLXML) { - try { - return ((org.postgresql.jdbc.PgSQLXML) in).getString(); - } catch (Exception e) { - return ""; - } - } else if (in instanceof java.sql.SQLXML) { - return in.toString(); - } else if (in.getClass().getName().equals("oracle.sql.INTERVALDS")) { - return in.toString(); - } else if (in.getClass().getName().equals("oracle.sql.INTERVALYM")) { - return in.toString(); - } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { - return in.toString(); - } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { - return in.toString(); - } else if (in.getClass().getName().equals("oracle.sql.BFILE")) { - Class clz = in.getClass(); - try { - Method methodFileExists = clz.getMethod("fileExists"); - boolean exists = (boolean) methodFileExists.invoke(in); - if (!exists) { - return ""; - } - - Method methodOpenFile = clz.getMethod("openFile"); - methodOpenFile.invoke(in); - - try { - Method methodCharacterStreamValue = clz.getMethod("getBinaryStream"); - java.io.InputStream is = (java.io.InputStream) methodCharacterStreamValue.invoke(in); - - String line; - StringBuilder sb = new StringBuilder(); - - java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(is)); - while ((line = br.readLine()) != null) { - sb.append(line); - } - - return sb.toString(); - } finally { - Method methodCloseFile = clz.getMethod("closeFile"); - methodCloseFile.invoke(in); - } - } catch (java.lang.reflect.InvocationTargetException ex) { - log.warn("Error for handle oracle.sql.BFILE: ", ex); - return ""; - } catch (Exception e) { - throw new RuntimeException(e); - } - } else if (in.getClass().getName().equals("microsoft.sql.DateTimeOffset")) { - return in.toString(); - } else if (in instanceof byte[]) { - return new String((byte[]) in); - } - - return null; - } - - /** - * 将任意类型转换为java.lang.Byte类型 - * - * @param in 任意类型的对象实例 - * @return java.lang.Byte类型 - */ - private Byte castToByte(final Object in) { - if (in instanceof java.lang.Number) { - return ((java.lang.Number) in).byteValue(); - } else if (in instanceof java.util.Date) { - return Long.valueOf(((java.util.Date) in).getTime()).byteValue(); - } else if (in instanceof java.lang.String) { - try { - return Byte.parseByte(in.toString()); - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.lang.String类型转换为java.lang.Byte类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Character) { - try { - return Byte.parseByte(in.toString()); - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.lang.Character类型转换为java.lang.Byte类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - return Byte.parseByte(clob2Str((java.sql.Clob) in)); - } catch (NumberFormatException e) { - throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Byte类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Boolean) { - return (java.lang.Boolean) in ? (byte) 1 : (byte) 0; - } - - return null; - } - - /** - * 将任意类型转换为java.lang.Short类型 - * - * @param in 任意类型的对象实例 - * @return java.lang.Short类型 - */ - private Short castToShort(final Object in) { - if (in instanceof java.lang.Number) { - return ((java.lang.Number) in).shortValue(); - } else if (in instanceof java.lang.Byte) { - return (short) (((byte) in) & 0xff); - } else if (in instanceof java.util.Date) { - return (short) ((java.util.Date) in).getTime(); - } else if (in instanceof java.util.Calendar) { - return (short) ((java.util.Calendar) in).getTime().getTime(); - } else if (in instanceof java.time.LocalDateTime) { - return (short) java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); - } else if (in instanceof java.time.OffsetDateTime) { - return (short) java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - String s = in.toString().trim(); - if (s.equalsIgnoreCase("true")) { - return Short.valueOf((short) 1); - } else if (s.equalsIgnoreCase("false")) { - return Short.valueOf((short) 0); - } else { - return Short.parseShort(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.lang.String类型转换为java.lang.Short类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - String s = clob2Str((java.sql.Clob) in).trim(); - if (s.equalsIgnoreCase("true")) { - return Short.valueOf((short) 1); - } else if (s.equalsIgnoreCase("false")) { - return Short.valueOf((short) 0); - } else { - return Short.parseShort(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Short类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Boolean) { - return (java.lang.Boolean) in ? (short) 1 : (short) 0; - } - - return null; - } - - /** - * 将任意类型转换为java.lang.Integer类型 - * - * @param in 任意类型的对象实例 - * @return java.lang.Integer类型 - */ - private Integer castToInteger(final Object in) { - if (in instanceof java.lang.Number) { - return ((java.lang.Number) in).intValue(); - } else if (in instanceof java.lang.Byte) { - return (int) (((byte) in) & 0xff); - } else if (in instanceof java.util.Date) { - return (int) ((java.util.Date) in).getTime(); - } else if (in instanceof java.util.Calendar) { - return (int) ((java.util.Calendar) in).getTime().getTime(); - } else if (in instanceof java.time.LocalDateTime) { - return (int) java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); - } else if (in instanceof java.time.OffsetDateTime) { - return (int) java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - String s = in.toString().trim(); - if (s.equalsIgnoreCase("true")) { - return Integer.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Integer.valueOf(0); - } else { - return Integer.parseInt(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.lang.String类型转换为java.lang.Integer类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - String s = clob2Str((java.sql.Clob) in).trim(); - if (s.equalsIgnoreCase("true")) { - return Integer.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Integer.valueOf(0); - } else { - return Integer.parseInt(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.sql.Clob类型转换为java.lang.Integer类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Boolean) { - return (java.lang.Boolean) in ? (int) 1 : (int) 0; - } - - return null; - } - - /** - * 将任意类型转换为java.lang.Long类型 - * - * @param in 任意类型的对象实例 - * @return java.lang.Long类型 - */ - private Long castToLong(final Object in) { - if (in instanceof java.lang.Number) { - return ((java.lang.Number) in).longValue(); - } else if (in instanceof java.lang.Byte) { - return (long) (((byte) in) & 0xff); - } else if (in instanceof java.util.Date) { - return ((java.util.Date) in).getTime(); - } else if (in instanceof java.util.Calendar) { - return ((java.util.Calendar) in).getTime().getTime(); - } else if (in instanceof java.time.LocalDateTime) { - return java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); - } else if (in instanceof java.time.OffsetDateTime) { - return java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - String s = in.toString().trim(); - if (s.equalsIgnoreCase("true")) { - return Long.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Long.valueOf(0); - } else { - return Long.parseLong(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.lang.String类型转换为java.lang.Long类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - String s = clob2Str((java.sql.Clob) in).trim(); - if (s.equalsIgnoreCase("true")) { - return Long.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Long.valueOf(0); - } else { - return Long.parseLong(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Long类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Boolean) { - return (java.lang.Boolean) in ? (long) 1 : (long) 0; - } - - return null; - } - - /** - * 将任意类型转换为java.lang.Number类型 - * - * @param in 任意类型的对象实例 - * @return java.lang.Number类型 - */ - private Number castToNumeric(final Object in) { - if (in instanceof java.lang.Number) { - return (java.lang.Number) in; - } else if (in instanceof java.util.Date) { - return ((java.util.Date) in).getTime(); - } else if (in instanceof java.util.Calendar) { - return ((java.util.Calendar) in).getTime().getTime(); - } else if (in instanceof java.time.LocalDateTime) { - return java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); - } else if (in instanceof java.time.OffsetDateTime) { - return java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - String s = in.toString().trim(); - if (s.equalsIgnoreCase("true")) { - return Integer.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Integer.valueOf(0); - } else { - return new java.math.BigDecimal(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.lang.String类型转换为java.lang.Number类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - String s = clob2Str((java.sql.Clob) in).trim(); - if (s.equalsIgnoreCase("true")) { - return Integer.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Integer.valueOf(0); - } else { - return new java.math.BigDecimal(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Number类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Boolean) { - return (java.lang.Boolean) in ? (long) 1 : (long) 0; - } - - return null; - } - - /** - * 将任意类型转换为java.lang.Float类型 - * - * @param in 任意类型的对象实例 - * @return java.lang.Float类型 - */ - private Float castToFloat(final Object in) { - if (in instanceof java.lang.Number) { - return ((java.lang.Number) in).floatValue(); - } else if (in instanceof java.util.Date) { - return (float) ((java.util.Date) in).getTime(); - } else if (in instanceof java.util.Calendar) { - return (float) ((java.util.Calendar) in).getTime().getTime(); - } else if (in instanceof java.time.LocalDateTime) { - return (float) java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); - } else if (in instanceof java.time.OffsetDateTime) { - return (float) java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - String s = in.toString().trim(); - if (s.equalsIgnoreCase("true")) { - return Float.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Float.valueOf(0); - } else { - return Float.parseFloat(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.lang.String类型转换为java.lang.Float类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - String s = clob2Str((java.sql.Clob) in).trim(); - if (s.equalsIgnoreCase("true")) { - return Float.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Float.valueOf(0); - } else { - return Float.parseFloat(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Float类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Boolean) { - return (java.lang.Boolean) in ? 1f : 0f; - } - - return null; - } - - /** - * 将任意类型转换为java.lang.Double类型 - * - * @param in 任意类型的对象实例 - * @return java.lang.Double类型 - */ - private Double castToDouble(final Object in) { - if (in instanceof java.lang.Number) { - return ((java.lang.Number) in).doubleValue(); - } else if (in instanceof java.util.Date) { - return (double) ((java.util.Date) in).getTime(); - } else if (in instanceof java.util.Calendar) { - return (double) ((java.util.Calendar) in).getTime().getTime(); - } else if (in instanceof java.time.LocalDateTime) { - return (double) java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); - } else if (in instanceof java.time.OffsetDateTime) { - return (double) java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - String s = in.toString().trim(); - if (s.equalsIgnoreCase("true")) { - return Double.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Double.valueOf(0); - } else { - return Double.parseDouble(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将将java.lang.String类型转换为java.lang.Double类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - String s = clob2Str((java.sql.Clob) in).trim(); - if (s.equalsIgnoreCase("true")) { - return Double.valueOf(1); - } else if (s.equalsIgnoreCase("false")) { - return Double.valueOf(0); - } else { - return Double.parseDouble(s); - } - } catch (NumberFormatException e) { - throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Double类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Boolean) { - return (java.lang.Boolean) in ? 1d : 0d; - } - - return null; - } - - /** - * 将任意类型转换为java.time.LocalDate类型 - * - * @param in 任意类型的对象实例 - * @return java.time.LocalDate类型 - */ - private LocalDate castToLocalDate(final Object in) { - if (in instanceof java.sql.Time) { - java.sql.Time date = (java.sql.Time) in; - LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); - return localDate; - } else if (in instanceof java.sql.Timestamp) { - java.sql.Timestamp t = (java.sql.Timestamp) in; - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime.toLocalDate(); - } else if (in instanceof java.util.Date) { - java.util.Date date = (java.util.Date) in; - LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); - return localDate; - } else if (in instanceof java.util.Calendar) { - java.sql.Date date = new java.sql.Date(((java.util.Calendar) in).getTime().getTime()); - LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); - return localDate; - } else if (in instanceof java.time.LocalDate) { - return (java.time.LocalDate) in; - } else if (in instanceof java.time.LocalTime) { - return java.time.LocalDate.MIN; - } else if (in instanceof java.time.LocalDateTime) { - return ((java.time.LocalDateTime) in).toLocalDate(); - } else if (in instanceof java.time.OffsetDateTime) { - return ((java.time.OffsetDateTime) in).toLocalDate(); - } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMP")) { - Class clz = in.getClass(); - try { - Method m = clz.getMethod("timestampValue"); - java.sql.Timestamp date = (java.sql.Timestamp) m.invoke(in); - LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); - return localDate; - } catch (Exception e) { - throw new RuntimeException(e); - } - } else if (in.getClass().getName().equals("microsoft.sql.DateTimeOffset")) { - Class clz = in.getClass(); - try { - Method m = clz.getMethod("getTimestamp"); - java.sql.Timestamp t = (java.sql.Timestamp) m.invoke(in); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime.toLocalDate(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - java.sql.Time date = java.sql.Time.valueOf(in.toString()); - LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); - return localDate; - } catch (IllegalArgumentException e) { - throw new RuntimeException(String.format("无法将java.lang.String类型转换为java.sql.Time类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - java.sql.Time date = java.sql.Time.valueOf(clob2Str((java.sql.Clob) in)); - LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); - return localDate; - } catch (NumberFormatException e) { - throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.sql.Time类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Number) { - java.sql.Timestamp t = new java.sql.Timestamp(((java.lang.Number) in).longValue()); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime.toLocalDate(); - } - - return null; - } - - /** - * 将任意类型转换为java.time.LocalTime类型 - * - * @param in 任意类型的对象实例 - * @return java.time.LocalDate类型 - */ - private LocalTime castToLocalTime(final Object in) { - if (in instanceof java.sql.Time) { - java.sql.Time date = (java.sql.Time) in; - LocalTime localTime = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalTime(); - return localTime; - } else if (in instanceof java.sql.Timestamp) { - java.sql.Timestamp t = (java.sql.Timestamp) in; - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime.toLocalTime(); - } else if (in instanceof java.util.Date) { - return LocalTime.of(0, 0, 0); - } else if (in instanceof java.util.Calendar) { - java.sql.Date date = new java.sql.Date(((java.util.Calendar) in).getTime().getTime()); - LocalDateTime localDateTime = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()) - .toLocalDateTime(); - return localDateTime.toLocalTime(); - } else if (in instanceof java.time.LocalDate) { - return LocalTime.of(0, 0, 0); - } else if (in instanceof java.time.LocalTime) { - return (java.time.LocalTime) in; - } else if (in instanceof java.time.LocalDateTime) { - return ((java.time.LocalDateTime) in).toLocalTime(); - } else if (in instanceof java.time.OffsetDateTime) { - return ((java.time.OffsetDateTime) in).toLocalTime(); - } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMP")) { - Class clz = in.getClass(); - try { - Method m = clz.getMethod("timestampValue"); - java.sql.Timestamp date = (java.sql.Timestamp) m.invoke(in); - LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); - return localDateTime.toLocalTime(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else if (in.getClass().getName().equals("microsoft.sql.DateTimeOffset")) { - Class clz = in.getClass(); - try { - Method m = clz.getMethod("getTimestamp"); - java.sql.Timestamp t = (java.sql.Timestamp) m.invoke(in); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime.toLocalTime(); - } catch (Exception e) { - throw new RuntimeException(e); - } - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - java.sql.Time date = java.sql.Time.valueOf(in.toString()); - return LocalTime.ofSecondOfDay(date.getTime()); - } catch (IllegalArgumentException e) { - throw new RuntimeException(String.format("无法将java.lang.String类型转换为java.sql.Time类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - java.sql.Time date = java.sql.Time.valueOf(clob2Str((java.sql.Clob) in)); - return LocalTime.ofSecondOfDay(date.getTime()); - } catch (NumberFormatException e) { - throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.sql.Time类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Number) { - java.sql.Timestamp t = new java.sql.Timestamp(((java.lang.Number) in).longValue()); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime.toLocalTime(); - } - - return null; - } - - /** - * 将任意类型转换为java.time.LocalDateTime类型 - * - * @param in 任意类型的对象实例 - * @return java.time.LocalDateTime类型 - */ - private LocalDateTime castToLocalDateTime(final Object in) { - if (in instanceof java.sql.Timestamp) { - java.sql.Timestamp t = (java.sql.Timestamp) in; - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime; - } else if (in instanceof java.sql.Date) { - java.sql.Date date = (java.sql.Date) in; - LocalDate localDate = date.toLocalDate(); - LocalTime localTime = LocalTime.of(0, 0, 0); - LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); - return localDateTime; - } else if (in instanceof java.sql.Time) { - java.sql.Time date = (java.sql.Time) in; - java.sql.Timestamp t = new java.sql.Timestamp(date.getTime()); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime; - } else if (in instanceof java.util.Date) { - java.sql.Timestamp t = new java.sql.Timestamp(((java.util.Date) in).getTime()); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime; - } else if (in instanceof java.util.Calendar) { - java.sql.Timestamp t = new java.sql.Timestamp(((java.util.Calendar) in).getTime().getTime()); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime; - } else if (in instanceof java.time.LocalDate) { - LocalDate localDate = (java.time.LocalDate) in; - LocalTime localTime = LocalTime.of(0, 0, 0); - LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); - return localDateTime; - } else if (in instanceof java.time.LocalTime) { - LocalDate localDate = java.time.LocalDate.MIN; - LocalTime localTime = (java.time.LocalTime) in; - LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); - return localDateTime; - } else if (in instanceof java.time.LocalDateTime) { - return (java.time.LocalDateTime) in; - } else if (in instanceof java.time.OffsetDateTime) { - return ((java.time.OffsetDateTime) in).toLocalDateTime(); - } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMP")) { - Class clz = in.getClass(); - try { - Method m = clz.getMethod("timestampValue"); - java.sql.Timestamp t = (java.sql.Timestamp) m.invoke(in); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime; - } catch (Exception e) { - throw new RuntimeException(e); - } - } else if (in.getClass().getName().equals("microsoft.sql.DateTimeOffset")) { - Class clz = in.getClass(); - try { - Method m = clz.getMethod("getTimestamp"); - java.sql.Timestamp t = (java.sql.Timestamp) m.invoke(in); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime; - } catch (Exception e) { - throw new RuntimeException(e); - } - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - java.sql.Timestamp t = java.sql.Timestamp.valueOf(in.toString()); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime; - } catch (IllegalArgumentException e) { - throw new RuntimeException( - String.format("无法将java.lang.String类型转换为java.sql.TimeStamp类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - java.sql.Timestamp t = java.sql.Timestamp.valueOf(clob2Str((java.sql.Clob) in)); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime; - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.sql.Clob类型转换为java.sql.TimeStamp类型:%s", e.getMessage())); - } - } else if (in instanceof java.lang.Number) { - java.sql.Timestamp t = new java.sql.Timestamp(((java.lang.Number) in).longValue()); - LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); - return localDateTime; - } - - return null; - } - - /** - * 将任意类型转换为byte[]类型 - * - * @param in 任意类型的对象实例 - * @return byte[]类型 - */ - private byte[] castToByteArray(final Object in) { - if (in instanceof byte[]) { - return (byte[]) in; - } else if (in instanceof java.util.Date) { - return in.toString().getBytes(); - } else if (in instanceof java.sql.Blob) { - return blob2Bytes((java.sql.Blob) in); - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - return in.toString().getBytes(); - } else if (in instanceof java.sql.Clob) { - return clob2Str((java.sql.Clob) in).toString().getBytes(); - } else { - return toByteArray(in); - } - } - - /** - * 将任意类型转换为Boolean类型 - * - * @param in 任意类型的对象实例 - * @return Boolean类型 - */ - private Boolean castToBoolean(final Object in) { - if (in instanceof java.lang.Boolean) { - return (java.lang.Boolean) in; - } else if (in instanceof java.lang.Number) { - return ((java.lang.Number) in).intValue() != 0; - } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { - try { - return Boolean.parseBoolean(in.toString()); - } catch (IllegalArgumentException e) { - throw new RuntimeException( - String.format("无法将java.lang.String类型转换为java.lang.Boolean类型:%s", e.getMessage())); - } - } else if (in instanceof java.sql.Clob) { - try { - return Boolean.parseBoolean(clob2Str((java.sql.Clob) in)); - } catch (NumberFormatException e) { - throw new RuntimeException( - String.format("无法将java.sql.Clob类型转换为java.lang.Boolean类型:%s", e.getMessage())); - } - } - - return null; - } + protected Map columnType; + + public GreenplumCopyWriterImpl(DataSource dataSource) { + super(dataSource); + + this.columnType = null; + } + + @Override + public void prepareWrite(String schemaName, String tableName) { + String sql = String.format("SELECT * from \"%s\".\"%s\" where 1=2", schemaName, tableName); + Map columnMetaData = new HashMap(); + Boolean ret = this.jdbcTemplate.execute((Connection conn) -> { + Statement stmt = null; + ResultSet rs = null; + try { + stmt = conn.createStatement(); + rs = stmt.executeQuery(sql); + ResultSetMetaData rsMetaData = rs.getMetaData(); + for (int i = 0, len = rsMetaData.getColumnCount(); i < len; i++) { + columnMetaData.put(rsMetaData.getColumnName(i + 1), rsMetaData.getColumnType(i + 1)); + } + + return true; + } catch (Exception e) { + throw new RuntimeException( + String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName), e); + } finally { + JdbcUtils.closeResultSet(rs); + JdbcUtils.closeStatement(stmt); + } + }); + + if (ret.booleanValue()) { + this.schemaName = Objects.requireNonNull(schemaName, "schema-name名称为空,不合法!"); + this.tableName = Objects.requireNonNull(tableName, "table-name名称为空,不合法!"); + this.columnType = Objects.requireNonNull(columnMetaData); + + if (this.columnType.isEmpty()) { + throw new RuntimeException( + String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName)); + } + } else { + throw new RuntimeException("内部代码出现错误,请开发人员排查!"); + } + } + + @Override + public long write(List fieldNames, List recordValues) { + if (null == this.columnType || this.columnType.isEmpty()) { + throw new RuntimeException("请先调用prepareWrite()函数,或者出现内部代码集成调用错误!"); + } + + if (fieldNames.isEmpty()) { + throw new IllegalArgumentException("第一个参数[fieldNames]为空,无效!"); + } + + if (recordValues.isEmpty()) { + return 0; + } + + String[] columnNames = new String[fieldNames.size()]; + for (int i = 0; i < fieldNames.size(); ++i) { + String s = fieldNames.get(i); + if (!this.columnType.containsKey(s)) { + throw new RuntimeException(String.format("表%s.%s 中不存在字段名为%s的字段,请检查参数传入!", schemaName, tableName, s)); + } + + columnNames[i] = s; + } + + String schemaName = Objects.requireNonNull(this.schemaName, "schema-name名称为空,不合法!"); + String tableName = Objects.requireNonNull(this.tableName, "table-name名称为空,不合法!"); + SimpleRowWriter.Table table = new SimpleRowWriter.Table(schemaName, tableName, columnNames); + + Connection connection = null; + try { + connection = dataSource.getConnection(); + } catch (SQLException e) { + throw new RuntimeException(e); + } + + try (SimpleRowWriter pgwriter = new SimpleRowWriter(table, PostgreSqlUtils.getPGConnection(connection), + true);) { + pgwriter.enableNullCharacterHandler(); + + long count = recordValues.size(); + for (Object[] objects : recordValues) { + if (fieldNames.size() != objects.length) { + throw new RuntimeException( + String.format("传入的参数有误,字段列数%d与记录中的值个数%d不相符合", fieldNames.size(), objects.length)); + } + + /** + * 数据类型转换参考 + *

+ * 1. spring-jdbc: {@code org.springframework.jdbc.core.StatementCreatorUtils} + *

+ *

+ * 2. postgresql-driver: {@code org.postgresql.jdbc.PgPreparedStatement} + *

+ */ + pgwriter.startRow(new Consumer() { + + @Override + public void accept(SimpleRow row) { + for (int i = 0; i < objects.length; ++i) { + String fieldName = fieldNames.get(i); + Object fieldValue = objects[i]; + Integer fieldType = columnType.get(fieldName); + switch (fieldType) { + case Types.CHAR: + case Types.NCHAR: + case Types.VARCHAR: + case Types.LONGVARCHAR: + case Types.NVARCHAR: + case Types.LONGNVARCHAR: + if (null == fieldValue) { + row.setVarChar(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { + row.setVarChar(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { + row.setVarChar(i, null); + } else { + String val = castToString(fieldValue); + if (null == val) { + throw new RuntimeException(String.format( + "表[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.String/java.sql.Clob,而实际的数据类型为%s", + schemaName, tableName, fieldName, fieldValue.getClass().getName())); + } + + row.setVarChar(i, val); + } + break; + case Types.CLOB: + case Types.NCLOB: + if (null == fieldValue) { + row.setText(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { + row.setText(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { + row.setText(i, null); + } else { + String val = castToString(fieldValue); + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.String/java.sql.Clob,而实际的数据类型为%s", + schemaName, tableName, fieldName, fieldValue.getClass().getName())); + } + + row.setText(i, val); + } + break; + case Types.TINYINT: + if (null == fieldValue) { + row.setByte(i, null); + } else { + Byte val = null; + try { + val = castToByte(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转错误,应该为java.lang.Byte,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + + row.setByte(i, val); + } + break; + case Types.SMALLINT: + if (null == fieldValue) { + row.setShort(i, null); + } else { + Short val = null; + try { + val = castToShort(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Short,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + + row.setShort(i, val); + } + break; + case Types.INTEGER: + if (null == fieldValue) { + row.setInteger(i, null); + } else { + Integer val = null; + try { + val = castToInteger(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Integer,而实际的数据类型为%s", + schemaName, tableName, fieldName, fieldValue.getClass().getName())); + } + + row.setInteger(i, val); + } + break; + case Types.BIGINT: + if (null == fieldValue) { + row.setLong(i, null); + } else { + Long val = null; + try { + val = castToLong(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Long,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + + row.setLong(i, val); + } + break; + case Types.NUMERIC: + case Types.DECIMAL: + if (null == fieldValue) { + row.setNumeric(i, null); + } else { + Number val = null; + try { + val = castToNumeric(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Number,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + + row.setNumeric(i, val); + } + break; + case Types.FLOAT: + case Types.REAL: + if (null == fieldValue) { + row.setFloat(i, null); + } else { + Float val = null; + try { + val = castToFloat(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Float,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + + row.setFloat(i, val); + } + break; + case Types.DOUBLE: + if (null == fieldValue) { + row.setDouble(i, null); + } else { + Double val = null; + try { + val = castToDouble(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.lang.Double,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + row.setDouble(i, val); + } + break; + case Types.BOOLEAN: + case Types.BIT: + if (null == fieldValue) { + row.setBoolean(i, null); + } else { + Boolean val = null; + try { + val = castToBoolean(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型错误,应该为java.lang.Boolean,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + row.setBoolean(i, val); + } + break; + case Types.TIME: + if (null == fieldValue) { + row.setTime(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { + row.setTime(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { + row.setTime(i, null); + } else { + LocalTime val = null; + try { + val = castToLocalTime(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.sql.Time,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + row.setTime(i, val); + } + break; + case Types.DATE: + if (null == fieldValue) { + row.setDate(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { + row.setDate(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { + row.setDate(i, null); + } else { + LocalDate val = null; + try { + val = castToLocalDate(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型转换错误,应该为java.sql.Date,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + row.setDate(i, val); + } + break; + case Types.TIMESTAMP: + if (null == fieldValue) { + row.setTimeStamp(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { + row.setTimeStamp(i, null); + } else if (fieldValue.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { + row.setTimeStamp(i, null); + } else { + LocalDateTime val = null; + try { + val = castToLocalDateTime(fieldValue); + } catch (RuntimeException e) { + throw new RuntimeException(String.format("表名[%s.%s]的字段名[%s]数据类型转错误,%s", + schemaName, tableName, fieldName, e.getMessage())); + } + + if (null == val) { + throw new RuntimeException(String.format( + "表名[%s.%s]的字段名[%s]数据类型错误,应该为java.sql.Timestamp,而实际的数据类型为%s", schemaName, + tableName, fieldName, fieldValue.getClass().getName())); + } + + row.setTimeStamp(i, val); + } + break; + case Types.BINARY: + case Types.VARBINARY: + case Types.BLOB: + case Types.LONGVARBINARY: + if (null == fieldValue) { + row.setByteArray(i, null); + } else { + row.setByteArray(i, castToByteArray(fieldValue)); + } + break; + case Types.NULL: + case Types.OTHER: + if (null == fieldValue) { + row.setText(i, null); + } else { + row.setText(i, fieldValue.toString()); + } + break; + default: + throw new RuntimeException(String.format("不支持的数据库字段类型,表名[%s.%s] 字段名[%s].", schemaName, + tableName, fieldName)); + } + } + } + }); + } + + return count; + } catch (SQLException e) { + throw new RuntimeException(e); + } finally { + JdbcUtils.closeConnection(connection); + } + + } + + /** + * 将java.sql.Clob类型转换为java.lang.String类型 + * + * @param clob java.sql.Clob类型对象 + * @return java.lang.String类型数据 + */ + private String clob2Str(java.sql.Clob clob) { + if (null == clob) { + return null; + } + + java.io.Reader is = null; + java.io.BufferedReader reader = null; + try { + is = clob.getCharacterStream(); + reader = new java.io.BufferedReader(is); + String line = reader.readLine(); + StringBuilder sb = new StringBuilder(); + while (line != null) { + sb.append(line); + line = reader.readLine(); + } + return sb.toString(); + } catch (SQLException | java.io.IOException e) { + throw new RuntimeException(e); + } finally { + try { + if (null != reader) { + reader.close(); + } + if (null != is) { + is.close(); + } + } catch (Exception ex) { + + } + } + } + + /** + * 将java.sql.Blob类型转换为byte数组 + * + * @param blob java.sql.Blob类型对象 + * @return byte数组 + */ + private byte[] blob2Bytes(java.sql.Blob blob) { + if (null == blob) { + return null; + } + + java.io.BufferedInputStream bufferedInputStream = null; + try { + bufferedInputStream = new java.io.BufferedInputStream(blob.getBinaryStream()); + byte[] bytes = new byte[(int) blob.length()]; + int len = bytes.length; + int offset = 0; + int read = 0; + while (offset < len && (read = bufferedInputStream.read(bytes, offset, len - offset)) >= 0) { + offset += read; + } + return bytes; + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + try { + bufferedInputStream.close(); + } catch (Exception e) { + } + } + } + + /** + * 将Object对象转换为字节数组 + * + * @param obj 对象 + * @return 字节数组 + */ + private byte[] toByteArray(Object obj) { + if (null == obj) { + return null; + } + + ByteArrayOutputStream bos = null; + ObjectOutputStream oos = null; + try { + bos = new ByteArrayOutputStream(); + oos = new ObjectOutputStream(bos); + oos.writeObject(obj); + oos.flush(); + return bos.toByteArray(); + } catch (Exception e) { + throw new RuntimeException(e); + } finally { + try { + if (null != oos) { + oos.close(); + } + + if (null != bos) { + bos.close(); + } + } catch (Exception e) { + } + } + } + + /** + * 将任意类型转换为java.lang.String类型 + * + * @param in 任意类型的对象实例 + * @return java.lang.String类型 + */ + private String castToString(final Object in) { + if (in instanceof java.lang.Character) { + return in.toString(); + } else if (in instanceof java.lang.String) { + return in.toString(); + } else if (in instanceof java.lang.Character) { + return in.toString(); + } else if (in instanceof java.sql.Clob) { + return clob2Str((java.sql.Clob) in); + } else if (in instanceof java.lang.Number) { + return in.toString(); + } else if (in instanceof java.sql.RowId) { + return in.toString(); + } else if (in instanceof java.lang.Boolean) { + return in.toString(); + } else if (in instanceof java.util.Date) { + return in.toString(); + } else if (in instanceof java.time.LocalDate) { + return in.toString(); + } else if (in instanceof java.time.LocalTime) { + return in.toString(); + } else if (in instanceof java.time.LocalDateTime) { + return in.toString(); + } else if (in instanceof java.time.OffsetDateTime) { + return in.toString(); + } else if (in instanceof java.util.UUID) { + return in.toString(); + } else if (in instanceof org.postgresql.util.PGobject) { + return in.toString(); + } else if (in instanceof org.postgresql.jdbc.PgSQLXML) { + try { + return ((org.postgresql.jdbc.PgSQLXML) in).getString(); + } catch (Exception e) { + return ""; + } + } else if (in instanceof java.sql.SQLXML) { + return in.toString(); + } else if (in.getClass().getName().equals("oracle.sql.INTERVALDS")) { + return in.toString(); + } else if (in.getClass().getName().equals("oracle.sql.INTERVALYM")) { + return in.toString(); + } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMPLTZ")) { + return in.toString(); + } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMPTZ")) { + return in.toString(); + } else if (in.getClass().getName().equals("oracle.sql.BFILE")) { + Class clz = in.getClass(); + try { + Method methodFileExists = clz.getMethod("fileExists"); + boolean exists = (boolean) methodFileExists.invoke(in); + if (!exists) { + return ""; + } + + Method methodOpenFile = clz.getMethod("openFile"); + methodOpenFile.invoke(in); + + try { + Method methodCharacterStreamValue = clz.getMethod("getBinaryStream"); + java.io.InputStream is = (java.io.InputStream) methodCharacterStreamValue.invoke(in); + + String line; + StringBuilder sb = new StringBuilder(); + + java.io.BufferedReader br = new java.io.BufferedReader(new java.io.InputStreamReader(is)); + while ((line = br.readLine()) != null) { + sb.append(line); + } + + return sb.toString(); + } finally { + Method methodCloseFile = clz.getMethod("closeFile"); + methodCloseFile.invoke(in); + } + } catch (java.lang.reflect.InvocationTargetException ex) { + log.warn("Error for handle oracle.sql.BFILE: ", ex); + return ""; + } catch (Exception e) { + throw new RuntimeException(e); + } + } else if (in.getClass().getName().equals("microsoft.sql.DateTimeOffset")) { + return in.toString(); + } else if (in instanceof byte[]) { + return new String((byte[]) in); + } + + return null; + } + + /** + * 将任意类型转换为java.lang.Byte类型 + * + * @param in 任意类型的对象实例 + * @return java.lang.Byte类型 + */ + private Byte castToByte(final Object in) { + if (in instanceof java.lang.Number) { + return ((java.lang.Number) in).byteValue(); + } else if (in instanceof java.util.Date) { + return Long.valueOf(((java.util.Date) in).getTime()).byteValue(); + } else if (in instanceof java.lang.String) { + try { + return Byte.parseByte(in.toString()); + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.lang.String类型转换为java.lang.Byte类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Character) { + try { + return Byte.parseByte(in.toString()); + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.lang.Character类型转换为java.lang.Byte类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + return Byte.parseByte(clob2Str((java.sql.Clob) in)); + } catch (NumberFormatException e) { + throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Byte类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Boolean) { + return (java.lang.Boolean) in ? (byte) 1 : (byte) 0; + } + + return null; + } + + /** + * 将任意类型转换为java.lang.Short类型 + * + * @param in 任意类型的对象实例 + * @return java.lang.Short类型 + */ + private Short castToShort(final Object in) { + if (in instanceof java.lang.Number) { + return ((java.lang.Number) in).shortValue(); + } else if (in instanceof java.lang.Byte) { + return (short) (((byte) in) & 0xff); + } else if (in instanceof java.util.Date) { + return (short) ((java.util.Date) in).getTime(); + } else if (in instanceof java.util.Calendar) { + return (short) ((java.util.Calendar) in).getTime().getTime(); + } else if (in instanceof java.time.LocalDateTime) { + return (short) java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); + } else if (in instanceof java.time.OffsetDateTime) { + return (short) java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + String s = in.toString().trim(); + if (s.equalsIgnoreCase("true")) { + return Short.valueOf((short) 1); + } else if (s.equalsIgnoreCase("false")) { + return Short.valueOf((short) 0); + } else { + return Short.parseShort(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.lang.String类型转换为java.lang.Short类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + String s = clob2Str((java.sql.Clob) in).trim(); + if (s.equalsIgnoreCase("true")) { + return Short.valueOf((short) 1); + } else if (s.equalsIgnoreCase("false")) { + return Short.valueOf((short) 0); + } else { + return Short.parseShort(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Short类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Boolean) { + return (java.lang.Boolean) in ? (short) 1 : (short) 0; + } + + return null; + } + + /** + * 将任意类型转换为java.lang.Integer类型 + * + * @param in 任意类型的对象实例 + * @return java.lang.Integer类型 + */ + private Integer castToInteger(final Object in) { + if (in instanceof java.lang.Number) { + return ((java.lang.Number) in).intValue(); + } else if (in instanceof java.lang.Byte) { + return (int) (((byte) in) & 0xff); + } else if (in instanceof java.util.Date) { + return (int) ((java.util.Date) in).getTime(); + } else if (in instanceof java.util.Calendar) { + return (int) ((java.util.Calendar) in).getTime().getTime(); + } else if (in instanceof java.time.LocalDateTime) { + return (int) java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); + } else if (in instanceof java.time.OffsetDateTime) { + return (int) java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + String s = in.toString().trim(); + if (s.equalsIgnoreCase("true")) { + return Integer.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Integer.valueOf(0); + } else { + return Integer.parseInt(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.lang.String类型转换为java.lang.Integer类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + String s = clob2Str((java.sql.Clob) in).trim(); + if (s.equalsIgnoreCase("true")) { + return Integer.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Integer.valueOf(0); + } else { + return Integer.parseInt(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.sql.Clob类型转换为java.lang.Integer类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Boolean) { + return (java.lang.Boolean) in ? (int) 1 : (int) 0; + } + + return null; + } + + /** + * 将任意类型转换为java.lang.Long类型 + * + * @param in 任意类型的对象实例 + * @return java.lang.Long类型 + */ + private Long castToLong(final Object in) { + if (in instanceof java.lang.Number) { + return ((java.lang.Number) in).longValue(); + } else if (in instanceof java.lang.Byte) { + return (long) (((byte) in) & 0xff); + } else if (in instanceof java.util.Date) { + return ((java.util.Date) in).getTime(); + } else if (in instanceof java.util.Calendar) { + return ((java.util.Calendar) in).getTime().getTime(); + } else if (in instanceof java.time.LocalDateTime) { + return java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); + } else if (in instanceof java.time.OffsetDateTime) { + return java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + String s = in.toString().trim(); + if (s.equalsIgnoreCase("true")) { + return Long.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Long.valueOf(0); + } else { + return Long.parseLong(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.lang.String类型转换为java.lang.Long类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + String s = clob2Str((java.sql.Clob) in).trim(); + if (s.equalsIgnoreCase("true")) { + return Long.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Long.valueOf(0); + } else { + return Long.parseLong(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Long类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Boolean) { + return (java.lang.Boolean) in ? (long) 1 : (long) 0; + } + + return null; + } + + /** + * 将任意类型转换为java.lang.Number类型 + * + * @param in 任意类型的对象实例 + * @return java.lang.Number类型 + */ + private Number castToNumeric(final Object in) { + if (in instanceof java.lang.Number) { + return (java.lang.Number) in; + } else if (in instanceof java.util.Date) { + return ((java.util.Date) in).getTime(); + } else if (in instanceof java.util.Calendar) { + return ((java.util.Calendar) in).getTime().getTime(); + } else if (in instanceof java.time.LocalDateTime) { + return java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); + } else if (in instanceof java.time.OffsetDateTime) { + return java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + String s = in.toString().trim(); + if (s.equalsIgnoreCase("true")) { + return Integer.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Integer.valueOf(0); + } else { + return new java.math.BigDecimal(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.lang.String类型转换为java.lang.Number类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + String s = clob2Str((java.sql.Clob) in).trim(); + if (s.equalsIgnoreCase("true")) { + return Integer.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Integer.valueOf(0); + } else { + return new java.math.BigDecimal(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Number类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Boolean) { + return (java.lang.Boolean) in ? (long) 1 : (long) 0; + } + + return null; + } + + /** + * 将任意类型转换为java.lang.Float类型 + * + * @param in 任意类型的对象实例 + * @return java.lang.Float类型 + */ + private Float castToFloat(final Object in) { + if (in instanceof java.lang.Number) { + return ((java.lang.Number) in).floatValue(); + } else if (in instanceof java.util.Date) { + return (float) ((java.util.Date) in).getTime(); + } else if (in instanceof java.util.Calendar) { + return (float) ((java.util.Calendar) in).getTime().getTime(); + } else if (in instanceof java.time.LocalDateTime) { + return (float) java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); + } else if (in instanceof java.time.OffsetDateTime) { + return (float) java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + String s = in.toString().trim(); + if (s.equalsIgnoreCase("true")) { + return Float.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Float.valueOf(0); + } else { + return Float.parseFloat(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.lang.String类型转换为java.lang.Float类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + String s = clob2Str((java.sql.Clob) in).trim(); + if (s.equalsIgnoreCase("true")) { + return Float.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Float.valueOf(0); + } else { + return Float.parseFloat(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Float类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Boolean) { + return (java.lang.Boolean) in ? 1f : 0f; + } + + return null; + } + + /** + * 将任意类型转换为java.lang.Double类型 + * + * @param in 任意类型的对象实例 + * @return java.lang.Double类型 + */ + private Double castToDouble(final Object in) { + if (in instanceof java.lang.Number) { + return ((java.lang.Number) in).doubleValue(); + } else if (in instanceof java.util.Date) { + return (double) ((java.util.Date) in).getTime(); + } else if (in instanceof java.util.Calendar) { + return (double) ((java.util.Calendar) in).getTime().getTime(); + } else if (in instanceof java.time.LocalDateTime) { + return (double) java.sql.Timestamp.valueOf((java.time.LocalDateTime) in).getTime(); + } else if (in instanceof java.time.OffsetDateTime) { + return (double) java.sql.Timestamp.valueOf(((java.time.OffsetDateTime) in).toLocalDateTime()).getTime(); + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + String s = in.toString().trim(); + if (s.equalsIgnoreCase("true")) { + return Double.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Double.valueOf(0); + } else { + return Double.parseDouble(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将将java.lang.String类型转换为java.lang.Double类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + String s = clob2Str((java.sql.Clob) in).trim(); + if (s.equalsIgnoreCase("true")) { + return Double.valueOf(1); + } else if (s.equalsIgnoreCase("false")) { + return Double.valueOf(0); + } else { + return Double.parseDouble(s); + } + } catch (NumberFormatException e) { + throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.lang.Double类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Boolean) { + return (java.lang.Boolean) in ? 1d : 0d; + } + + return null; + } + + /** + * 将任意类型转换为java.time.LocalDate类型 + * + * @param in 任意类型的对象实例 + * @return java.time.LocalDate类型 + */ + private LocalDate castToLocalDate(final Object in) { + if (in instanceof java.sql.Time) { + java.sql.Time date = (java.sql.Time) in; + LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate; + } else if (in instanceof java.sql.Timestamp) { + java.sql.Timestamp t = (java.sql.Timestamp) in; + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime.toLocalDate(); + } else if (in instanceof java.util.Date) { + java.util.Date date = (java.util.Date) in; + LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate; + } else if (in instanceof java.util.Calendar) { + java.sql.Date date = new java.sql.Date(((java.util.Calendar) in).getTime().getTime()); + LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate; + } else if (in instanceof java.time.LocalDate) { + return (java.time.LocalDate) in; + } else if (in instanceof java.time.LocalTime) { + return java.time.LocalDate.MIN; + } else if (in instanceof java.time.LocalDateTime) { + return ((java.time.LocalDateTime) in).toLocalDate(); + } else if (in instanceof java.time.OffsetDateTime) { + return ((java.time.OffsetDateTime) in).toLocalDate(); + } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMP")) { + Class clz = in.getClass(); + try { + Method m = clz.getMethod("timestampValue"); + java.sql.Timestamp date = (java.sql.Timestamp) m.invoke(in); + LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate; + } catch (Exception e) { + throw new RuntimeException(e); + } + } else if (in.getClass().getName().equals("microsoft.sql.DateTimeOffset")) { + Class clz = in.getClass(); + try { + Method m = clz.getMethod("getTimestamp"); + java.sql.Timestamp t = (java.sql.Timestamp) m.invoke(in); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime.toLocalDate(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + java.sql.Time date = java.sql.Time.valueOf(in.toString()); + LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate; + } catch (IllegalArgumentException e) { + throw new RuntimeException(String.format("无法将java.lang.String类型转换为java.sql.Time类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + java.sql.Time date = java.sql.Time.valueOf(clob2Str((java.sql.Clob) in)); + LocalDate localDate = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDate(); + return localDate; + } catch (NumberFormatException e) { + throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.sql.Time类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Number) { + java.sql.Timestamp t = new java.sql.Timestamp(((java.lang.Number) in).longValue()); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime.toLocalDate(); + } + + return null; + } + + /** + * 将任意类型转换为java.time.LocalTime类型 + * + * @param in 任意类型的对象实例 + * @return java.time.LocalDate类型 + */ + private LocalTime castToLocalTime(final Object in) { + if (in instanceof java.sql.Time) { + java.sql.Time date = (java.sql.Time) in; + LocalTime localTime = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalTime(); + return localTime; + } else if (in instanceof java.sql.Timestamp) { + java.sql.Timestamp t = (java.sql.Timestamp) in; + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime.toLocalTime(); + } else if (in instanceof java.util.Date) { + return LocalTime.of(0, 0, 0); + } else if (in instanceof java.util.Calendar) { + java.sql.Date date = new java.sql.Date(((java.util.Calendar) in).getTime().getTime()); + LocalDateTime localDateTime = Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()) + .toLocalDateTime(); + return localDateTime.toLocalTime(); + } else if (in instanceof java.time.LocalDate) { + return LocalTime.of(0, 0, 0); + } else if (in instanceof java.time.LocalTime) { + return (java.time.LocalTime) in; + } else if (in instanceof java.time.LocalDateTime) { + return ((java.time.LocalDateTime) in).toLocalTime(); + } else if (in instanceof java.time.OffsetDateTime) { + return ((java.time.OffsetDateTime) in).toLocalTime(); + } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMP")) { + Class clz = in.getClass(); + try { + Method m = clz.getMethod("timestampValue"); + java.sql.Timestamp date = (java.sql.Timestamp) m.invoke(in); + LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); + return localDateTime.toLocalTime(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else if (in.getClass().getName().equals("microsoft.sql.DateTimeOffset")) { + Class clz = in.getClass(); + try { + Method m = clz.getMethod("getTimestamp"); + java.sql.Timestamp t = (java.sql.Timestamp) m.invoke(in); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime.toLocalTime(); + } catch (Exception e) { + throw new RuntimeException(e); + } + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + java.sql.Time date = java.sql.Time.valueOf(in.toString()); + return LocalTime.ofSecondOfDay(date.getTime()); + } catch (IllegalArgumentException e) { + throw new RuntimeException(String.format("无法将java.lang.String类型转换为java.sql.Time类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + java.sql.Time date = java.sql.Time.valueOf(clob2Str((java.sql.Clob) in)); + return LocalTime.ofSecondOfDay(date.getTime()); + } catch (NumberFormatException e) { + throw new RuntimeException(String.format("无法将java.sql.Clob类型转换为java.sql.Time类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Number) { + java.sql.Timestamp t = new java.sql.Timestamp(((java.lang.Number) in).longValue()); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime.toLocalTime(); + } + + return null; + } + + /** + * 将任意类型转换为java.time.LocalDateTime类型 + * + * @param in 任意类型的对象实例 + * @return java.time.LocalDateTime类型 + */ + private LocalDateTime castToLocalDateTime(final Object in) { + if (in instanceof java.sql.Timestamp) { + java.sql.Timestamp t = (java.sql.Timestamp) in; + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime; + } else if (in instanceof java.sql.Date) { + java.sql.Date date = (java.sql.Date) in; + LocalDate localDate = date.toLocalDate(); + LocalTime localTime = LocalTime.of(0, 0, 0); + LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); + return localDateTime; + } else if (in instanceof java.sql.Time) { + java.sql.Time date = (java.sql.Time) in; + java.sql.Timestamp t = new java.sql.Timestamp(date.getTime()); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime; + } else if (in instanceof java.util.Date) { + java.sql.Timestamp t = new java.sql.Timestamp(((java.util.Date) in).getTime()); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime; + } else if (in instanceof java.util.Calendar) { + java.sql.Timestamp t = new java.sql.Timestamp(((java.util.Calendar) in).getTime().getTime()); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime; + } else if (in instanceof java.time.LocalDate) { + LocalDate localDate = (java.time.LocalDate) in; + LocalTime localTime = LocalTime.of(0, 0, 0); + LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); + return localDateTime; + } else if (in instanceof java.time.LocalTime) { + LocalDate localDate = java.time.LocalDate.MIN; + LocalTime localTime = (java.time.LocalTime) in; + LocalDateTime localDateTime = LocalDateTime.of(localDate, localTime); + return localDateTime; + } else if (in instanceof java.time.LocalDateTime) { + return (java.time.LocalDateTime) in; + } else if (in instanceof java.time.OffsetDateTime) { + return ((java.time.OffsetDateTime) in).toLocalDateTime(); + } else if (in.getClass().getName().equals("oracle.sql.TIMESTAMP")) { + Class clz = in.getClass(); + try { + Method m = clz.getMethod("timestampValue"); + java.sql.Timestamp t = (java.sql.Timestamp) m.invoke(in); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime; + } catch (Exception e) { + throw new RuntimeException(e); + } + } else if (in.getClass().getName().equals("microsoft.sql.DateTimeOffset")) { + Class clz = in.getClass(); + try { + Method m = clz.getMethod("getTimestamp"); + java.sql.Timestamp t = (java.sql.Timestamp) m.invoke(in); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime; + } catch (Exception e) { + throw new RuntimeException(e); + } + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + java.sql.Timestamp t = java.sql.Timestamp.valueOf(in.toString()); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime; + } catch (IllegalArgumentException e) { + throw new RuntimeException( + String.format("无法将java.lang.String类型转换为java.sql.TimeStamp类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + java.sql.Timestamp t = java.sql.Timestamp.valueOf(clob2Str((java.sql.Clob) in)); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime; + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.sql.Clob类型转换为java.sql.TimeStamp类型:%s", e.getMessage())); + } + } else if (in instanceof java.lang.Number) { + java.sql.Timestamp t = new java.sql.Timestamp(((java.lang.Number) in).longValue()); + LocalDateTime localDateTime = LocalDateTime.ofInstant(t.toInstant(), ZoneId.systemDefault()); + return localDateTime; + } + + return null; + } + + /** + * 将任意类型转换为byte[]类型 + * + * @param in 任意类型的对象实例 + * @return byte[]类型 + */ + private byte[] castToByteArray(final Object in) { + if (in instanceof byte[]) { + return (byte[]) in; + } else if (in instanceof java.util.Date) { + return in.toString().getBytes(); + } else if (in instanceof java.sql.Blob) { + return blob2Bytes((java.sql.Blob) in); + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + return in.toString().getBytes(); + } else if (in instanceof java.sql.Clob) { + return clob2Str((java.sql.Clob) in).toString().getBytes(); + } else { + return toByteArray(in); + } + } + + /** + * 将任意类型转换为Boolean类型 + * + * @param in 任意类型的对象实例 + * @return Boolean类型 + */ + private Boolean castToBoolean(final Object in) { + if (in instanceof java.lang.Boolean) { + return (java.lang.Boolean) in; + } else if (in instanceof java.lang.Number) { + return ((java.lang.Number) in).intValue() != 0; + } else if (in instanceof java.lang.String || in instanceof java.lang.Character) { + try { + return Boolean.parseBoolean(in.toString()); + } catch (IllegalArgumentException e) { + throw new RuntimeException( + String.format("无法将java.lang.String类型转换为java.lang.Boolean类型:%s", e.getMessage())); + } + } else if (in instanceof java.sql.Clob) { + try { + return Boolean.parseBoolean(clob2Str((java.sql.Clob) in)); + } catch (NumberFormatException e) { + throw new RuntimeException( + String.format("无法将java.sql.Clob类型转换为java.lang.Boolean类型:%s", e.getMessage())); + } + } + + return null; + } } \ No newline at end of file diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/gpdb/GreenplumInsertWriterImpl.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/gpdb/GreenplumInsertWriterImpl.java index 7c9bbee7..d8114819 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/gpdb/GreenplumInsertWriterImpl.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/gpdb/GreenplumInsertWriterImpl.java @@ -4,12 +4,12 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter.gpdb; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Objects; import javax.sql.DataSource; @@ -26,60 +26,56 @@ import lombok.extern.slf4j.Slf4j; /** * Greenplum数据库Insert写入实现类 - * - * @author tang * + * @author tang */ @Slf4j public class GreenplumInsertWriterImpl extends AbstractDatabaseWriter implements IDatabaseWriter { - public GreenplumInsertWriterImpl(DataSource dataSource) { - super(dataSource); - } + public GreenplumInsertWriterImpl(DataSource dataSource) { + super(dataSource); + } - @Override - public long write(List fieldNames, List recordValues) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } + @Override + public long write(List fieldNames, List recordValues) { + String schemaName = Objects.requireNonNull(this.schemaName, "schema-name名称为空,不合法!"); + String tableName = Objects.requireNonNull(this.tableName, "table-name名称为空,不合法!"); - String schemaName = Objects.requireNonNull(this.schemaName, "schema-name名称为空,不合法!"); - String tableName = Objects.requireNonNull(this.tableName, "table-name名称为空,不合法!"); - String sqlInsert = String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, - StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); - int[] argTypes = new int[fieldNames.size()]; - for (int i = 0; i < fieldNames.size(); ++i) { - String col = fieldNames.get(i); - argTypes[i] = this.columnType.get(col); - } + String sqlInsert = String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, + StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); - DefaultTransactionDefinition defination = new DefaultTransactionDefinition(); - defination.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); - defination.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - PlatformTransactionManager transactionManager = new DataSourceTransactionManager( - this.jdbcTemplate.getDataSource()); - TransactionStatus status = transactionManager.getTransaction(defination); + int[] argTypes = new int[fieldNames.size()]; + for (int i = 0; i < fieldNames.size(); ++i) { + String col = fieldNames.get(i); + argTypes[i] = this.columnType.get(col); + } - try { - int[] affects = jdbcTemplate.batchUpdate(sqlInsert, recordValues, argTypes); - int affectCount = 0; - for (int i : affects) { - affectCount += i; - } + DefaultTransactionDefinition defination = new DefaultTransactionDefinition(); + defination.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); + defination.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); + PlatformTransactionManager transactionManager = new DataSourceTransactionManager(this.dataSource); + TransactionStatus status = transactionManager.getTransaction(defination); - recordValues.clear(); - transactionManager.commit(status); - return affectCount; - } catch (TransactionException e) { - transactionManager.rollback(status); - throw e; - } catch (Exception e) { - transactionManager.rollback(status); - throw e; - } + try { + int[] affects = jdbcTemplate.batchUpdate(sqlInsert, recordValues, argTypes); + int affectCount = 0; + for (int i : affects) { + affectCount += i; + } - } + recordValues.clear(); + transactionManager.commit(status); + return affectCount; + } catch (TransactionException e) { + transactionManager.rollback(status); + throw e; + } catch (Exception e) { + transactionManager.rollback(status); + throw e; + } + + } } diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/kingbase/KingbaseCopyWriterImpl.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/kingbase/KingbaseCopyWriterImpl.java index 41b97f4f..365e23cd 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/kingbase/KingbaseCopyWriterImpl.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/kingbase/KingbaseCopyWriterImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter.kingbase; @@ -13,6 +13,12 @@ import javax.sql.DataSource; import com.gitee.dbswitch.dbwriter.IDatabaseWriter; import com.gitee.dbswitch.dbwriter.gpdb.GreenplumCopyWriterImpl; +/** + * Kingbase8数据库Copy写入实现类 + * + * @author tang + * + */ public class KingbaseCopyWriterImpl extends GreenplumCopyWriterImpl implements IDatabaseWriter { public KingbaseCopyWriterImpl(DataSource dataSource) { diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/kingbase/KingbaseInsertWriterImpl.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/kingbase/KingbaseInsertWriterImpl.java index 5a1490ef..6b7b7597 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/kingbase/KingbaseInsertWriterImpl.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/kingbase/KingbaseInsertWriterImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter.kingbase; @@ -13,6 +13,12 @@ import javax.sql.DataSource; import com.gitee.dbswitch.dbwriter.IDatabaseWriter; import com.gitee.dbswitch.dbwriter.gpdb.GreenplumInsertWriterImpl; +/** + * Kingbase8数据库Insert写入实现类 + * + * @author tang + * + */ public class KingbaseInsertWriterImpl extends GreenplumInsertWriterImpl implements IDatabaseWriter { public KingbaseInsertWriterImpl(DataSource dataSource) { diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/mssql/SqlServerWriterImpl.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/mssql/SqlServerWriterImpl.java index 8be78e4a..ccd8355d 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/mssql/SqlServerWriterImpl.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/mssql/SqlServerWriterImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter.mssql; @@ -12,17 +12,10 @@ package com.gitee.dbswitch.dbwriter.mssql; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; -import java.sql.SQLException; import java.sql.Statement; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.ConnectionCallback; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.transaction.PlatformTransactionManager; @@ -36,106 +29,97 @@ import lombok.extern.slf4j.Slf4j; /** * SQLServer批量写入实现类 - * - * @author tang * + * @author tang */ @Slf4j public class SqlServerWriterImpl extends AbstractDatabaseWriter implements IDatabaseWriter { - public SqlServerWriterImpl(DataSource dataSource) { - super(dataSource); - } + public SqlServerWriterImpl(DataSource dataSource) { + super(dataSource); + } - @Override - public void prepareWrite(String schemaName, String tableName) { - String sql = String.format("SELECT * FROM [%s].[%s] WHERE 1=2", schemaName, tableName); - Map columnMetaData = new HashMap(); - Boolean ret = this.jdbcTemplate.execute(new ConnectionCallback() { + @Override + public void prepareWrite(String schemaName, String tableName) { + String sql = String.format("SELECT * FROM [%s].[%s] WHERE 1=2", schemaName, tableName); + Map columnMetaData = new HashMap(); + Boolean ret = this.jdbcTemplate.execute((Connection conn) -> { + Statement stmt = null; + ResultSet rs = null; + try { + stmt = conn.createStatement(); + rs = stmt.executeQuery(sql); + ResultSetMetaData rsMetaData = rs.getMetaData(); + for (int i = 0, len = rsMetaData.getColumnCount(); i < len; i++) { + columnMetaData.put(rsMetaData.getColumnName(i + 1), rsMetaData.getColumnType(i + 1)); + } - @Override - public Boolean doInConnection(Connection conn) throws SQLException, DataAccessException { - Statement stmt = null; - ResultSet rs = null; - try { - stmt = conn.createStatement(); - rs = stmt.executeQuery(sql); - ResultSetMetaData rsMetaData = rs.getMetaData(); - for (int i = 0, len = rsMetaData.getColumnCount(); i < len; i++) { - columnMetaData.put(rsMetaData.getColumnName(i + 1), rsMetaData.getColumnType(i + 1)); - } + return true; + } catch (Exception e) { + throw new RuntimeException(String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName), e); + } finally { + JdbcUtils.closeResultSet(rs); + JdbcUtils.closeStatement(stmt); + } + }); - return true; - } catch (Exception e) { - throw new RuntimeException( - String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName), e); - } finally { - JdbcUtils.closeResultSet(rs); - JdbcUtils.closeStatement(stmt); - } - } - }); + if (ret.booleanValue()) { + this.schemaName = schemaName; + this.tableName = tableName; + this.columnType = Objects.requireNonNull(columnMetaData); - if (ret) { - this.schemaName = schemaName; - this.tableName = tableName; - this.columnType = Objects.requireNonNull(columnMetaData); + if (this.columnType.isEmpty()) { + throw new RuntimeException( + String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName)); + } + } else { + throw new RuntimeException("内部代码出现错误,请开发人员排查!"); + } + } - if (this.columnType.isEmpty()) { - throw new RuntimeException( - String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName)); - } - } else { - throw new RuntimeException("内部代码出现错误,请开发人员排查!"); - } - } - - @Override - public long write(List fieldNames, List recordValues) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } + @Override + public long write(List fieldNames, List recordValues) { + String schemaName = Objects.requireNonNull(this.schemaName, "schema名称为空,不合法!"); + String tableName = Objects.requireNonNull(this.tableName, "table名称为空,不合法!"); - String schemaName = Objects.requireNonNull(this.schemaName, "schema名称为空,不合法!"); - String tableName = Objects.requireNonNull(this.tableName, "table名称为空,不合法!"); - String sqlInsert = String.format("INSERT INTO [%s].[%s] ( [%s] ) VALUES ( %s )", schemaName, tableName, - StringUtils.join(fieldNames, "],["), StringUtils.join(placeHolders, ",")); + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); - int[] argTypes = new int[fieldNames.size()]; - for (int i = 0; i < fieldNames.size(); ++i) { - String col = fieldNames.get(i); - argTypes[i] = this.columnType.get(col); - } + String sqlInsert = String.format("INSERT INTO [%s].[%s] ( [%s] ) VALUES ( %s )", schemaName, tableName, + StringUtils.join(fieldNames, "],["), StringUtils.join(placeHolders, ",")); - DefaultTransactionDefinition defination = new DefaultTransactionDefinition(); - defination.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); - defination.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); - PlatformTransactionManager transactionManager = new DataSourceTransactionManager( - this.jdbcTemplate.getDataSource()); - TransactionStatus status = transactionManager.getTransaction(defination); + int[] argTypes = new int[fieldNames.size()]; + for (int i = 0; i < fieldNames.size(); ++i) { + String col = fieldNames.get(i); + argTypes[i] = this.columnType.get(col); + } - try { - int[] affects = jdbcTemplate.batchUpdate(sqlInsert, recordValues, argTypes); - int affectCount = 0; - for (int i : affects) { - affectCount += i; - } + DefaultTransactionDefinition defination = new DefaultTransactionDefinition(); + defination.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); + defination.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); + PlatformTransactionManager transactionManager = new DataSourceTransactionManager(this.dataSource); + TransactionStatus status = transactionManager.getTransaction(defination); - recordValues.clear(); - transactionManager.commit(status); - if (log.isDebugEnabled()) { - log.debug("SQL Server insert data affect count: {}", affectCount); - } - return affectCount; - } catch (TransactionException e) { - transactionManager.rollback(status); - throw e; - } catch (Exception e) { - transactionManager.rollback(status); - throw e; - } + try { + int[] affects = jdbcTemplate.batchUpdate(sqlInsert, recordValues, argTypes); + int affectCount = 0; + for (int i : affects) { + affectCount += i; + } - } + recordValues.clear(); + transactionManager.commit(status); + if (log.isDebugEnabled()) { + log.debug("SQL Server insert data affect count: {}", affectCount); + } + return affectCount; + } catch (TransactionException e) { + transactionManager.rollback(status); + throw e; + } catch (Exception e) { + transactionManager.rollback(status); + throw e; + } + + } } diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/mysql/MySqlWriterImpl.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/mysql/MySqlWriterImpl.java index 66d07692..a56f3a72 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/mysql/MySqlWriterImpl.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/mysql/MySqlWriterImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter.mysql; @@ -12,24 +12,16 @@ package com.gitee.dbswitch.dbwriter.mysql; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; -import java.sql.SQLException; import java.sql.Statement; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Objects; +import java.util.*; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; -import org.springframework.dao.DataAccessException; -import org.springframework.jdbc.core.ConnectionCallback; import org.springframework.jdbc.datasource.DataSourceTransactionManager; import org.springframework.jdbc.support.JdbcUtils; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.TransactionDefinition; import org.springframework.transaction.TransactionStatus; import org.springframework.transaction.support.DefaultTransactionDefinition; -import org.springframework.transaction.support.TransactionCallback; import org.springframework.transaction.support.TransactionTemplate; import com.gitee.dbswitch.dbwriter.AbstractDatabaseWriter; import com.gitee.dbswitch.dbwriter.IDatabaseWriter; @@ -58,33 +50,28 @@ public class MySqlWriterImpl extends AbstractDatabaseWriter implements IDatabase @Override public void prepareWrite(String schemaName, String tableName) { String sql = String.format("SELECT * FROM `%s`.`%s` WHERE 1=2", schemaName, tableName); - Map columnMetaData = new HashMap(); - Boolean ret = this.jdbcTemplate.execute(new ConnectionCallback() { - - @Override - public Boolean doInConnection(Connection conn) throws SQLException, DataAccessException { - Statement stmt = null; - ResultSet rs = null; - try { - stmt = conn.createStatement(); - rs = stmt.executeQuery(sql); - ResultSetMetaData rsMetaData = rs.getMetaData(); - for (int i = 0, len = rsMetaData.getColumnCount(); i < len; i++) { - columnMetaData.put(rsMetaData.getColumnName(i + 1), rsMetaData.getColumnType(i + 1)); - } - - return true; - } catch (Exception e) { - throw new RuntimeException( - String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName), e); - } finally { - JdbcUtils.closeResultSet(rs); - JdbcUtils.closeStatement(stmt); + Map columnMetaData = new HashMap<>(); + Boolean ret = this.jdbcTemplate.execute((Connection conn) -> { + Statement stmt = null; + ResultSet rs = null; + try { + stmt = conn.createStatement(); + rs = stmt.executeQuery(sql); + ResultSetMetaData rsMetaData = rs.getMetaData(); + for (int i = 0, len = rsMetaData.getColumnCount(); i < len; i++) { + columnMetaData.put(rsMetaData.getColumnName(i + 1), rsMetaData.getColumnType(i + 1)); } + + return true; + } catch (Exception e) { + throw new RuntimeException(String.format("获取表:%s.%s 的字段的元信息时失败. 请联系 DBA 核查该库、表信息.", schemaName, tableName), e); + } finally { + JdbcUtils.closeResultSet(rs); + JdbcUtils.closeStatement(stmt); } }); - if (ret) { + if (ret.booleanValue()) { this.schemaName = schemaName; this.tableName = tableName; this.columnType = Objects.requireNonNull(columnMetaData); @@ -100,13 +87,11 @@ public class MySqlWriterImpl extends AbstractDatabaseWriter implements IDatabase @Override public long write(List fieldNames, List recordValues) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } - String schemaName = Objects.requireNonNull(this.schemaName, "schema-name名称为空,不合法!"); String tableName = Objects.requireNonNull(this.tableName, "table-name名称为空,不合法!"); + + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); + String sqlInsert = String.format("INSERT INTO `%s`.`%s` ( `%s` ) VALUES ( %s )", schemaName, tableName, StringUtils.join(fieldNames, "`,`"), StringUtils.join(placeHolders, ",")); @@ -118,21 +103,17 @@ public class MySqlWriterImpl extends AbstractDatabaseWriter implements IDatabase PlatformTransactionManager transactionManager = new DataSourceTransactionManager(this.dataSource); TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager, definition); - Integer ret = transactionTemplate.execute(new TransactionCallback() { - - @Override - public Integer doInTransaction(TransactionStatus transactionStatus) { - try { - int[] affects = jdbcTemplate.batchUpdate(sqlInsert, recordValues, argTypes); - int affectCount = 0; - for (int i : affects) { - affectCount += i; - } - return affectCount; - } catch (Throwable t) { - transactionStatus.setRollbackOnly(); - throw t; + Integer ret = transactionTemplate.execute((TransactionStatus transactionStatus) -> { + try { + int[] affects = jdbcTemplate.batchUpdate(sqlInsert, recordValues, argTypes); + int affectCount = 0; + for (int i : affects) { + affectCount += i; } + return affectCount; + } catch (Throwable t) { + transactionStatus.setRollbackOnly(); + throw t; } }); diff --git a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/oracle/OracleWriterImpl.java b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/oracle/OracleWriterImpl.java index fdec14d4..37280596 100644 --- a/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/oracle/OracleWriterImpl.java +++ b/dbswitch-dbwriter/src/main/java/com/gitee/dbswitch/dbwriter/oracle/OracleWriterImpl.java @@ -4,13 +4,17 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.dbwriter.oracle; +import java.io.BufferedReader; +import java.io.IOException; +import java.sql.Clob; +import java.sql.SQLException; +import java.util.Collections; import java.util.List; -import java.util.ArrayList; import java.util.Objects; import javax.sql.DataSource; import org.apache.commons.lang3.StringUtils; @@ -38,13 +42,11 @@ public class OracleWriterImpl extends AbstractDatabaseWriter implements IDatabas @Override public long write(List fieldNames, List recordValues) { - List placeHolders = new ArrayList(); - for (int i = 0; i < fieldNames.size(); ++i) { - placeHolders.add("?"); - } - String schemaName = Objects.requireNonNull(this.schemaName, "schema-name名称为空,不合法!"); String tableName = Objects.requireNonNull(this.tableName, "table-name名称为空,不合法!"); + + List placeHolders = Collections.nCopies(fieldNames.size(), "?"); + String sqlInsert = String.format("INSERT INTO \"%s\".\"%s\" ( \"%s\" ) VALUES ( %s )", schemaName, tableName, StringUtils.join(fieldNames, "\",\""), StringUtils.join(placeHolders, ",")); @@ -54,6 +56,18 @@ public class OracleWriterImpl extends AbstractDatabaseWriter implements IDatabas argTypes[i] = this.columnType.get(col); } + /** 处理Oracle的Clob类型需写入String类型的数据的问题 */ + recordValues.parallelStream().forEach((Object[] row) -> { + for (int i = 0; i < row.length; ++i) { + try { + row[i] = convertClobToString(row[i]); + } catch (Exception e) { + log.warn("Field Value convert from java.sql.Clob to java.lang.String failed, field name is : {} ", fieldNames.get(i)); + row[i] = null; + } + } + }); + DefaultTransactionDefinition definition = new DefaultTransactionDefinition(); definition.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED); definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED); @@ -82,4 +96,48 @@ public class OracleWriterImpl extends AbstractDatabaseWriter implements IDatabas } + /** + * 将java.sql.Clob 类型转换为java.lang.String + * @param o + * @return + * @throws SQLException + * @throws IOException + */ + private Object convertClobToString(Object o) throws SQLException, IOException { + if (null == o) { + return null; + } + + if (o instanceof Clob) { + Clob clob = (Clob) o; + java.io.Reader is = null; + java.io.BufferedReader reader = null; + try { + is = clob.getCharacterStream(); + reader = new java.io.BufferedReader(is); + String line = reader.readLine(); + StringBuilder sb = new StringBuilder(); + while (line != null) { + sb.append(line); + line = reader.readLine(); + } + return sb.toString(); + } catch (SQLException | java.io.IOException e) { + throw new RuntimeException(e); + } finally { + try { + if (null != reader) { + reader.close(); + } + if (null != is) { + is.close(); + } + } catch (Exception ex) { + } + } + } + + return o; + } + } diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheMssqlSqlDialect.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheMssqlSqlDialect.java index 82e5a266..55ee6dc2 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheMssqlSqlDialect.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheMssqlSqlDialect.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.calcite; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheMysqlSqlDialect.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheMysqlSqlDialect.java index 3225eb7e..ac01336c 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheMysqlSqlDialect.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheMysqlSqlDialect.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.calcite; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheOracleSqlDialect.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheOracleSqlDialect.java index 98e0ed52..f5181cd6 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheOracleSqlDialect.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheOracleSqlDialect.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.calcite; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/ThePostgresqlSqlDialect.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/ThePostgresqlSqlDialect.java index 1b323f57..b16addc6 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/ThePostgresqlSqlDialect.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/ThePostgresqlSqlDialect.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.calcite; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheSqlOrderBy.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheSqlOrderBy.java index 2299ff08..1980e660 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheSqlOrderBy.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheSqlOrderBy.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.calcite; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheSqlRowOperator.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheSqlRowOperator.java index 0996773f..35fbbb2e 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheSqlRowOperator.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/calcite/TheSqlRowOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.calcite; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/constant/Const.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/constant/Const.java index 96042e30..fb2ae516 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/constant/Const.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/constant/Const.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.constant; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/AbstractDatabaseDialect.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/AbstractDatabaseDialect.java index df125594..79d9da1a 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/AbstractDatabaseDialect.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/AbstractDatabaseDialect.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/AbstractSqlDdlOperator.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/AbstractSqlDdlOperator.java index 4ccaf2cb..b88e593f 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/AbstractSqlDdlOperator.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/AbstractSqlDdlOperator.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/pojo/ColumnDefinition.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/pojo/ColumnDefinition.java index 27d2f85d..9dcd7e97 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/pojo/ColumnDefinition.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/pojo/ColumnDefinition.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.pojo; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/pojo/TableDefinition.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/pojo/TableDefinition.java index eab038d9..7584409c 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/pojo/TableDefinition.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/pojo/TableDefinition.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.pojo; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlAlterTable.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlAlterTable.java index 18f83105..c215cbbc 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlAlterTable.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlAlterTable.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.sql; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlCreateTable.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlCreateTable.java index 75d17799..e5ff7373 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlCreateTable.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlCreateTable.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.sql; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlDropTable.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlDropTable.java index 5b36f30f..b674d8cf 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlDropTable.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlDropTable.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.sql; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlTruncateTable.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlTruncateTable.java index 7069c131..6211ec15 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlTruncateTable.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/DdlSqlTruncateTable.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.sql; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/GreenplumDialectImpl.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/GreenplumDialectImpl.java index b5e52526..9c4c8d82 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/GreenplumDialectImpl.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/GreenplumDialectImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.sql.impl; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/MySqlDialectImpl.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/MySqlDialectImpl.java index 27815d6e..4b7b272e 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/MySqlDialectImpl.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/MySqlDialectImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.sql.impl; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/OracleDialectImpl.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/OracleDialectImpl.java index c29e2f95..76e2f854 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/OracleDialectImpl.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/OracleDialectImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.sql.impl; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/PostgresDialectImpl.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/PostgresDialectImpl.java index 894c21cf..dfef0739 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/PostgresDialectImpl.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/sql/impl/PostgresDialectImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.sql.impl; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/GreenplumDataTypeEnum.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/GreenplumDataTypeEnum.java index 0ef228f0..9018fb89 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/GreenplumDataTypeEnum.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/GreenplumDataTypeEnum.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.type; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/MySqlDataTypeEnum.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/MySqlDataTypeEnum.java index d3e900b3..d32f73f0 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/MySqlDataTypeEnum.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/MySqlDataTypeEnum.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.type; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/OracleDataTypeEnum.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/OracleDataTypeEnum.java index f3dee85e..1c206988 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/OracleDataTypeEnum.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/OracleDataTypeEnum.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.type; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/PostgresDataTypeEnum.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/PostgresDataTypeEnum.java index 94500418..c09c0901 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/PostgresDataTypeEnum.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/ddl/type/PostgresDataTypeEnum.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.ddl.type; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/ISqlConvertService.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/ISqlConvertService.java index 3c6cf82e..fd81703c 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/ISqlConvertService.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/ISqlConvertService.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.service; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/ISqlGeneratorService.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/ISqlGeneratorService.java index bc4d027d..36b742fa 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/ISqlGeneratorService.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/ISqlGeneratorService.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.service; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/impl/CalciteSqlConvertServiceImpl.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/impl/CalciteSqlConvertServiceImpl.java index 23c74c3a..4239264a 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/impl/CalciteSqlConvertServiceImpl.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/impl/CalciteSqlConvertServiceImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.service.impl; diff --git a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/impl/MyselfSqlGeneratorServiceImpl.java b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/impl/MyselfSqlGeneratorServiceImpl.java index f46a22d9..6c8c949f 100644 --- a/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/impl/MyselfSqlGeneratorServiceImpl.java +++ b/dbswitch-sql/src/main/java/com/gitee/dbswitch/sql/service/impl/MyselfSqlGeneratorServiceImpl.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.sql.service.impl; @@ -56,32 +56,32 @@ public class MyselfSqlGeneratorServiceImpl implements ISqlGeneratorService { } @Override - public String createTable(String dbtype, TableDefinition t) { - DatabaseTypeEnum type = DatabaseTypeEnum.valueOf(dbtype.toUpperCase()); + public String createTable(String dbType, TableDefinition t) { + DatabaseTypeEnum type = DatabaseTypeEnum.valueOf(dbType.toUpperCase()); AbstractDatabaseDialect dialect = getDatabaseInstance(type); AbstractSqlDdlOperator operator = new DdlSqlCreateTable(t); return operator.toSqlString(dialect); } @Override - public String alterTable(String dbtype, String handle, TableDefinition t){ - DatabaseTypeEnum type = DatabaseTypeEnum.valueOf(dbtype.toUpperCase()); + public String alterTable(String dbType, String handle, TableDefinition t){ + DatabaseTypeEnum type = DatabaseTypeEnum.valueOf(dbType.toUpperCase()); AbstractDatabaseDialect dialect = getDatabaseInstance(type); AbstractSqlDdlOperator operator = new DdlSqlAlterTable(t,handle); return operator.toSqlString(dialect); } @Override - public String dropTable(String dbtype, TableDefinition t) { - DatabaseTypeEnum type = DatabaseTypeEnum.valueOf(dbtype.toUpperCase()); + public String dropTable(String dbType, TableDefinition t) { + DatabaseTypeEnum type = DatabaseTypeEnum.valueOf(dbType.toUpperCase()); AbstractDatabaseDialect dialect = getDatabaseInstance(type); AbstractSqlDdlOperator operator = new DdlSqlDropTable(t); return operator.toSqlString(dialect); } @Override - public String truncateTable(String dbtype, TableDefinition t) { - DatabaseTypeEnum type = DatabaseTypeEnum.valueOf(dbtype.toUpperCase()); + public String truncateTable(String dbType, TableDefinition t) { + DatabaseTypeEnum type = DatabaseTypeEnum.valueOf(dbType.toUpperCase()); AbstractDatabaseDialect dialect = getDatabaseInstance(type); AbstractSqlDdlOperator operator = new DdlSqlTruncateTable(t); return operator.toSqlString(dialect); diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/WebServiceApplication.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/WebServiceApplication.java index f1c6aeaf..278497b9 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/WebServiceApplication.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/WebServiceApplication.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi; @@ -14,6 +14,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; +/** + * RESTful接口服务的启动类 + * + * @author tang + */ @SpringBootApplication(exclude= {DataSourceAutoConfiguration.class}) public class WebServiceApplication { diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/aspect/WebLogAspect.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/aspect/WebLogAspect.java index ee42a07e..cb8a3d4a 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/aspect/WebLogAspect.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/aspect/WebLogAspect.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Datae : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi.aspect; diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/ActuatorSecurityConfig.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/ActuatorSecurityConfig.java index 86a6f016..a9132549 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/ActuatorSecurityConfig.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/ActuatorSecurityConfig.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi.config; diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/AdapterBeanConfiguration.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/AdapterBeanConfiguration.java index f8a707c4..13498e95 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/AdapterBeanConfiguration.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/AdapterBeanConfiguration.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi.config; diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/SwaggerConfig.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/SwaggerConfig.java index 94bfd83d..09ad7e66 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/SwaggerConfig.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/config/SwaggerConfig.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi.config; diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/ConvertController.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/ConvertController.java index 790b8c5f..03fdde6f 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/ConvertController.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/ConvertController.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi.controller; diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/ExceptionController.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/ExceptionController.java index 73e36cfb..c6c0ec24 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/ExceptionController.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/ExceptionController.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi.controller; diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/GeneratorController.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/GeneratorController.java index 8cf7fba4..47905e93 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/GeneratorController.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/GeneratorController.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi.controller; diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/StructureController.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/StructureController.java index 3583cbb5..01c262ce 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/StructureController.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/controller/StructureController.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi.controller; diff --git a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/model/ResponseResult.java b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/model/ResponseResult.java index 2dd9fe50..55edc107 100644 --- a/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/model/ResponseResult.java +++ b/dbswitch-webapi/src/main/java/com/gitee/dbswitch/webapi/model/ResponseResult.java @@ -4,13 +4,12 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi.model; import java.io.Serializable; - import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; diff --git a/dbswitch-webapi/src/test/java/com/gitee/dbswitch/webapi/SwitchApplicationTests.java b/dbswitch-webapi/src/test/java/com/gitee/dbswitch/webapi/SwitchApplicationTests.java index 59e06e21..19cc4dca 100644 --- a/dbswitch-webapi/src/test/java/com/gitee/dbswitch/webapi/SwitchApplicationTests.java +++ b/dbswitch-webapi/src/test/java/com/gitee/dbswitch/webapi/SwitchApplicationTests.java @@ -4,7 +4,7 @@ // Use of this source code is governed by a BSD-style license // // Author: tang (inrgihc@126.com) -// Data : 2020/1/2 +// Date : 2020/1/2 // Location: beijing , china ///////////////////////////////////////////////////////////// package com.gitee.dbswitch.webapi; diff --git a/pom.xml b/pom.xml index 8ce0c290..23b95f76 100644 --- a/pom.xml +++ b/pom.xml @@ -9,6 +9,13 @@ + com.gitee + dbswitch + 1.5.4 + pom + dbswitch + database switch project + 1.8 3.1.1 @@ -19,13 +26,6 @@ UTF-8 - com.gitee - dbswitch - 1.5.4 - pom - dbswitch - database switch project - dbswitch-common dbswitch-core