QT(C++)根据两个数据库的映射关系复制数据库中的表的内容

一、源数据库与目标数据库之间的映射关系用Json文件保存:

[
    {
        "srcTable": "users",
        "destTable": "target_users",
        "fieldMap": {
            "id": "user_id",
            "name": "user_name"
        }
    },
    {
        "srcTable": "orders",
        "destTable": "target_orders",
        "fieldMap": {
            "order_id": "id",
            "amount": "total"
        }
    }
]

二、源数据库与目标数据库之间映射关系的数据结构设置为:

struct TableCopyConfig {
    QString srcTable;
    QString destTable;
    QMap<QString, QString> fieldMap;
};

三、读取JSON文件,并进行解析,保存到结构体列表中

#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
#include <QFile>
#include <QDebug>

QList<TableCopyConfig> readConfigsFromFile(const QString &filePath) {
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly)) {
        qWarning() << "无法打开文件:" << file.errorString();
        return QList<TableCopyConfig>();
    }

    QByteArray jsonData = file.readAll();
    file.close();

    return readConfigsFromJson(jsonData);
}

QList<TableCopyConfig> readConfigsFromJson(const QByteArray &jsonData) {
    QList<TableCopyConfig> configs;

    // 解析 JSON 文档
    QJsonParseError parseError;
    QJsonDocument doc = QJsonDocument::fromJson(jsonData, &parseError);
    if (parseError.error != QJsonParseError::NoError) {
        qWarning() << "JSON 解析错误:" << parseError.errorString();
        return configs;
    }

    // 检查 JSON 是否为数组
    if (!doc.isArray()) {
        qWarning() << "JSON 格式错误: 顶层数据应为数组";
        return configs;
    }

    // 遍历数组中的每个配置对象
    QJsonArray configsArray = doc.array();
    for (const QJsonValue &configValue : configsArray) {
        if (!configValue.isObject()) {
            qWarning() << "跳过非对象元素";
            continue;
        }

        QJsonObject configObj = configValue.toObject();
        TableCopyConfig config;

        // 提取 srcTable
        if (configObj.contains("srcTable") && configObj["srcTable"].isString()) {
            config.srcTable = configObj["srcTable"].toString();
        } else {
            qWarning() << "缺少或无效的 srcTable";
            continue;
        }

        // 提取 destTable
        if (configObj.contains("destTable") && configObj["destTable"].isString()) {
            config.destTable = configObj["destTable"].toString();
        } else {
            qWarning() << "缺少或无效的 destTable";
            continue;
        }

        // 提取 fieldMap
        if (configObj.contains("fieldMap") && configObj["fieldMap"].isObject()) {
            QJsonObject fieldMapObj = configObj["fieldMap"].toObject();
            for (const QString &key : fieldMapObj.keys()) {
                if (fieldMapObj[key].isString()) {
                    config.fieldMap[key] = fieldMapObj[key].toString();
                } else {
                    qWarning() << "字段" << key << "的值不是字符串";
                }
            }
        } else {
            qWarning() << "缺少或无效的 fieldMap";
            continue;
        }

        configs.append(config);
    }

    return configs;
}

四、根据映射关系列表复制数据

#include <QSqlDatabase>
#include <QSqlQuery>
#include <QSqlError>
#include <QDebug>
#include <QList>
#include <QMap>

struct TableCopyConfig {
    QString srcTable;
    QString destTable;
    QMap<QString, QString> fieldMap;
};

void copyFieldsBetweenDBs(const QString &srcDBPath, const QString &destDBPath, const QList<TableCopyConfig> &configs)
 {
    // 连接源数据库
    QSqlDatabase srcDb = QSqlDatabase::addDatabase("QSQLITE", "source_connection");
    srcDb.setDatabaseName("source.db");
    if (!srcDb.open()) {
        qDebug() << "源数据库连接失败:" << srcDb.lastError().text();
        return;
    }

    // 连接目标数据库
    QSqlDatabase destDb = QSqlDatabase::addDatabase("QSQLITE", "dest_connection");
    destDb.setDatabaseName("target.db");
    if (!destDb.open()) {
        qDebug() << "目标数据库连接失败:" << destDb.lastError().text();
        srcDb.close();
        return;
    }

    // 遍历每个表的配置
    for (const TableCopyConfig &config : configs) {
        QStringList srcFields = config.fieldMap.keys();
        QString selectSql = QString("SELECT %1 FROM %2")
                                .arg(srcFields.join(", "))
                                .arg(config.srcTable);

        QStringList destFields = config.fieldMap.values();
        QString insertSql = QString("INSERT INTO %1 (%2) VALUES (%3)")
                                .arg(config.destTable)
                                .arg(destFields.join(", "))
                                .arg(QStringList(destFields.size(), "?").join(", "));

        // 执行源表查询
        QSqlQuery srcQuery(srcDb);
        if (!srcQuery.exec(selectSql)) {
            qDebug() << "查询表" << config.srcTable << "失败:" << srcQuery.lastError().text();
            continue;
        }

        // 开启事务插入目标表
        destDb.transaction();
        QSqlQuery destQuery(destDb);

        while (srcQuery.next()) {
            QVariantList bindValues;
            for (const QString &srcField : srcFields) {
                bindValues.append(srcQuery.value(srcField));
            }

            destQuery.prepare(insertSql);
            for (const QVariant &value : bindValues) {
                destQuery.addBindValue(value);
            }

            if (!destQuery.exec()) {
                qDebug() << "插入到表" << config.destTable << "失败:" << destQuery.lastError().text();
                destDb.rollback();
                break;
            }
        }

        if (!destDb.commit()) {
            qDebug() << "提交事务失败:" << destDb.lastError().text();
        }
    }

    // 关闭连接
    srcDb.close();
    destDb.close();
    QSqlDatabase::removeDatabase("source_connection");
    QSqlDatabase::removeDatabase("dest_connection");
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值