一、源数据库与目标数据库之间的映射关系用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");
}