通过java同步mysql数据,根据两表字段值进行数据迁移(带去重+计算迁移量)

我做的是从源表中字段例如code=A123的对应信息同步到目标表中的字段例如也是code=A12的对应信息中,且A12在目标表内目前没数据。

public static void main(String[] args) {
        final String SOURCE_TABLE = "源表";
        final String TARGET_TABLE = "目标表";
        final String SOURCE_CHANNEL_CODE = "A123"; // 源表中要同步的 code 值
        final String TARGET_CHANNEL_CODE = "A12"; // 目标表中要同步的 code 值
        final String UNIQUE_COLUMN = "id"; // 用于去重的唯一标识符列

        try {
            // 建立数据库连接
            Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/数据库名", "用户名", "密码");

            // 获取源表的列信息
            DatabaseMetaData metaData = connection.getMetaData();
            ResultSet sourceColumns = metaData.getColumns(null, null, SOURCE_TABLE, null);

            // 创建 SQL 语句和准备好的语句
            StringBuilder insertColumns = new StringBuilder();
            StringBuilder values = new StringBuilder();
            StringBuilder updateSets = new StringBuilder();

            while (sourceColumns.next()) {
                String columnName = sourceColumns.getString("COLUMN_NAME");
                if (!columnName.equals("channel_code")) {
                    insertColumns.append(columnName).append(",");
                    values.append("?,");

                    updateSets.append(columnName).append(" = ?, ");
                }
            }

            // 移除多余的逗号
            insertColumns.deleteCharAt(insertColumns.length() - 1);
            values.deleteCharAt(values.length() - 1);
            updateSets.delete(updateSets.length() - 2, updateSets.length()); // 去除最后的逗号和空格

            // 完善 SQL 语句
            String insertTargetSql = "INSERT INTO " + TARGET_TABLE + " (" + insertColumns.toString() + ", code) VALUES (" + values.toString() + ", ?)";
            String selectSourceSql = "SELECT * FROM " + SOURCE_TABLE + " WHERE code = ?";
            String checkDuplicateSql = "SELECT COUNT(*) FROM " + TARGET_TABLE + " WHERE " + UNIQUE_COLUMN + " = ?";

            // 创建准备好的语句
            PreparedStatement selectSourceStatement = connection.prepareStatement(selectSourceSql);
            PreparedStatement checkDuplicateStatement = connection.prepareStatement(checkDuplicateSql);
            PreparedStatement insertTargetStatement = connection.prepareStatement(insertTargetSql);

            // 从源表中选择指定 channel_code 的记录
            selectSourceStatement.setString(1, SOURCE_CHANNEL_CODE);
            ResultSet sourceResult = selectSourceStatement.executeQuery();

            // 获取列数和处理每条记录
            ResultSetMetaData resultSetMetaData = sourceResult.getMetaData();
            int columnCount = resultSetMetaData.getColumnCount();
            int numMigrated = 0;

            // 找到 info_id 列的索引
            int infoIdIndex = -1;
            for (int i = 1; i <= columnCount; i++) {
                if (UNIQUE_COLUMN.equals(resultSetMetaData.getColumnName(i))) {
                    infoIdIndex = i;
                    break;
                }
            }

            if (infoIdIndex == -1) {
                throw new SQLException("Column " + UNIQUE_COLUMN + " not found in source table.");
            }

            // 遍历源表中的所有记录并插入到目标表中
            while (sourceResult.next()) {
                // 检查目标表中是否已存在相同 info_id
                checkDuplicateStatement.setObject(1, sourceResult.getObject(infoIdIndex));
                ResultSet checkResult = checkDuplicateStatement.executeQuery();
                checkResult.next();
                boolean exists = checkResult.getInt(1) > 0;

                if (!exists) {
                    // 插入新记录
                    int paramIndex = 1;
                    for (int i = 1; i <= columnCount; i++) {
                        String columnName = resultSetMetaData.getColumnName(i);
                        if (!columnName.equals("channel_code")) {
                            insertTargetStatement.setObject(paramIndex++, sourceResult.getObject(i));
                        }
                    }
                    numMigrated++;
                    // 设置新的 channel_code
                    insertTargetStatement.setString(paramIndex, TARGET_CHANNEL_CODE);

                    // 执行插入操作
                    insertTargetStatement.executeUpdate();
                }
            }

            System.out.println("数据同步成功!同步数量为:"+numMigrated);

            connection.close();

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WAZYY0619

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值