添加SQL语句批量执行接口
This commit is contained in:
parent
a39f8f2faf
commit
8b243cd535
|
|
@ -12,8 +12,15 @@ class SqlQueryExecutor : public QObject
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static SqlQueryExecutor& instance();
|
static SqlQueryExecutor& instance();
|
||||||
//基础SQL语句执行接口
|
//单条SQL语句执行接口
|
||||||
QSqlQuery executeSQL(const QString& strConnectionName, const QString& strSQL, const QVariantHash& params = {}, bool useTranscation = false);
|
QSqlQuery executeSQL(const QString& strConnectionName, const QString& strSQL, const QVariantHash& params = {}, bool useTranscation = false);
|
||||||
|
/**
|
||||||
|
* @brief 多条批量SQL语句执行接口
|
||||||
|
* @param sqlStatements SQL语句列表
|
||||||
|
* @param paramsList 参数列表(要与SQL语句一一对应)
|
||||||
|
*/
|
||||||
|
QSqlQuery executeBatchSQL(const QString& strConnectionName, const QStringList& sqlStatements,
|
||||||
|
const QList<QVariantHash>& paramsList = QList<QVariantHash>(), bool useTranscation = false);
|
||||||
//基于具体业务的查询接口-对外调用
|
//基于具体业务的查询接口-对外调用
|
||||||
const QVector<Model> getModels(const QString&);
|
const QVector<Model> getModels(const QString&);
|
||||||
const QVector<AttributeGroup> getAttributeGroup(const QString&);
|
const QVector<AttributeGroup> getAttributeGroup(const QString&);
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ SqlQueryExecutor::SqlQueryExecutor()
|
||||||
SqlQueryExecutor::~SqlQueryExecutor()
|
SqlQueryExecutor::~SqlQueryExecutor()
|
||||||
{}
|
{}
|
||||||
|
|
||||||
//基础SQL语句执行接口
|
//单条SQL语句执行接口
|
||||||
QSqlQuery SqlQueryExecutor::executeSQL(const QString& strConnectionName, const QString& strSQL, const QVariantHash& params, bool useTranscation)
|
QSqlQuery SqlQueryExecutor::executeSQL(const QString& strConnectionName, const QString& strSQL, const QVariantHash& params, bool useTranscation)
|
||||||
{
|
{
|
||||||
QSqlDatabase db = QSqlDatabase::database(strConnectionName);
|
QSqlDatabase db = QSqlDatabase::database(strConnectionName);
|
||||||
|
|
@ -79,6 +79,84 @@ QSqlQuery SqlQueryExecutor::executeSQL(const QString& strConnectionName, const Q
|
||||||
|
|
||||||
return sqlQuery;
|
return sqlQuery;
|
||||||
}
|
}
|
||||||
|
//多条批量SQL语句执行接口
|
||||||
|
QSqlQuery SqlQueryExecutor::executeBatchSQL(const QString& strConnectionName, const QStringList& sqlStatements, const QList<QVariantHash>& paramsList, bool useTranscation)
|
||||||
|
{
|
||||||
|
QSqlDatabase db = QSqlDatabase::database(strConnectionName);
|
||||||
|
if(!db.isOpen())
|
||||||
|
{
|
||||||
|
LOG_ERROR("DB", QString("Database not open. connectionName: %1").arg(strConnectionName));
|
||||||
|
throw DatabaseException(db.lastError());
|
||||||
|
}
|
||||||
|
|
||||||
|
//参数数量校验
|
||||||
|
if(!paramsList.isEmpty() && sqlStatements.size() != paramsList.size())
|
||||||
|
{
|
||||||
|
LOG_ERROR("SQL", QString("SQL statement does not match the number of parameters"));
|
||||||
|
throw DatabaseException(QSqlError("SQL statement does not match the number of parameters"));
|
||||||
|
}
|
||||||
|
|
||||||
|
//事务
|
||||||
|
bool transactionStarted = false;
|
||||||
|
if(useTranscation)
|
||||||
|
{
|
||||||
|
if(!db.transaction())
|
||||||
|
{
|
||||||
|
LOG_ERROR("DB", QString("Start transaction failed. connectionName: %1. error: %2").arg(strConnectionName, db.lastError().databaseText()));
|
||||||
|
throw DatabaseException(db.lastError());
|
||||||
|
}
|
||||||
|
transactionStarted = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QSqlQuery lastQuery(db);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
for(int i = 0; i < sqlStatements.size(); i++)
|
||||||
|
{
|
||||||
|
const QString& strSQL = sqlStatements.at(i);
|
||||||
|
const QVariantHash& params = paramsList.isEmpty() ? QVariantHash() : paramsList.at(i);
|
||||||
|
|
||||||
|
QSqlQuery sqlQuery(db);
|
||||||
|
if(!sqlQuery.prepare(strSQL))
|
||||||
|
{
|
||||||
|
LOG_ERROR("SQL", QString("SQL '%1' prepare fialed. error: %2").arg(strSQL, sqlQuery.lastError().databaseText()));
|
||||||
|
throw DatabaseException(db.lastError());
|
||||||
|
}
|
||||||
|
//绑定参数
|
||||||
|
for(auto it = params.constBegin(); it != params.constEnd(); it++)
|
||||||
|
{
|
||||||
|
sqlQuery.bindValue(it.key(), it.value());
|
||||||
|
}
|
||||||
|
if (!sqlQuery.exec())
|
||||||
|
{
|
||||||
|
LOG_ERROR("SQL", QString("SQL '%1' execute error: %2").arg(strSQL, sqlQuery.lastError().databaseText()));
|
||||||
|
throw DatabaseException(sqlQuery.lastError());
|
||||||
|
}
|
||||||
|
lastQuery = std::move(sqlQuery);
|
||||||
|
// 提交事务(如果已开启)
|
||||||
|
if(transactionStarted && !db.commit())
|
||||||
|
{
|
||||||
|
throw DatabaseException(db.lastError());
|
||||||
|
LOG_ERROR("DB", QString("Commit transaction failed. connectionName: %1. error: %2").arg(strConnectionName, db.lastError().databaseText()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (const DatabaseException& e)
|
||||||
|
{
|
||||||
|
// 错误处理:回滚事务(如果已开启)
|
||||||
|
if(transactionStarted)
|
||||||
|
{
|
||||||
|
if(!db.rollback()) // 回滚失败时记录警告
|
||||||
|
{
|
||||||
|
LOG_ERROR("DB", QString("Rollback failed. connectionName: %1. error: %2").arg(strConnectionName, db.lastError().databaseText()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw; // 重新抛出异常
|
||||||
|
}
|
||||||
|
|
||||||
|
return lastQuery;
|
||||||
|
}
|
||||||
|
|
||||||
//具体业务查询接口
|
//具体业务查询接口
|
||||||
const QVector<Model> SqlQueryExecutor::getModels(const QString& strConnectionName)
|
const QVector<Model> SqlQueryExecutor::getModels(const QString& strConnectionName)
|
||||||
|
|
@ -126,6 +204,20 @@ QVector<int> SqlQueryExecutor::getModelGroups(const QString& strConnectionName,
|
||||||
|
|
||||||
bool SqlQueryExecutor::addModel(const QString& connectionName, Model& model)
|
bool SqlQueryExecutor::addModel(const QString& connectionName, Model& model)
|
||||||
{
|
{
|
||||||
|
//属于批量操作,需要开启事务,因为后续插入映射表时需要先插入进model_type记录的自增id,所以无法在一个接口函数中执行,所以事务放在在接口外部执行
|
||||||
|
QSqlDatabase db = QSqlDatabase::database(connectionName);
|
||||||
|
if(!db.isOpen())
|
||||||
|
{
|
||||||
|
LOG_ERROR("DB", QString("Database not open. connectionName: %1").arg(connectionName));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!db.transaction())
|
||||||
|
{
|
||||||
|
LOG_ERROR("DB", QString("Start transaction failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int modelID = -1;
|
int modelID = -1;
|
||||||
//先向model_type中插入一条记录
|
//先向model_type中插入一条记录
|
||||||
QString strSQL = "INSERT INTO basic.model_type (model_type, model_name, remark) VALUES "
|
QString strSQL = "INSERT INTO basic.model_type (model_type, model_name, remark) VALUES "
|
||||||
|
|
@ -134,8 +226,6 @@ bool SqlQueryExecutor::addModel(const QString& connectionName, Model& model)
|
||||||
params.insert(":type", model.type);
|
params.insert(":type", model.type);
|
||||||
params.insert(":name", model.name);
|
params.insert(":name", model.name);
|
||||||
params.insert(":remark", model.remark);
|
params.insert(":remark", model.remark);
|
||||||
/*QString strSQL = "INSERT INTO basic.model_type (model_type, model_name, remark) VALUES (\'" +
|
|
||||||
model.type + "\',\'" + model.name + + "\',\'" + model.remark +"\')";*/
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
QSqlQuery query = executeSQL(connectionName, strSQL, params);
|
QSqlQuery query = executeSQL(connectionName, strSQL, params);
|
||||||
|
|
@ -144,30 +234,42 @@ bool SqlQueryExecutor::addModel(const QString& connectionName, Model& model)
|
||||||
}
|
}
|
||||||
catch (const DatabaseException& e)
|
catch (const DatabaseException& e)
|
||||||
{
|
{
|
||||||
|
if(!db.rollback()) // 回滚失败时记录警告
|
||||||
|
{
|
||||||
|
LOG_ERROR("DB", QString("Rollback failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText()));
|
||||||
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//然后向model_group中插入记录
|
//然后向model_group中插入记录,采用批量接口
|
||||||
|
QStringList sqlStatements;
|
||||||
|
QList<QVariantHash> paramsList;
|
||||||
for(int groupID : model.groups)
|
for(int groupID : model.groups)
|
||||||
{
|
{
|
||||||
/*strSQL = "INSERT INTO basic.model_group (model_type_id, attribute_group_id) VALUES (" +
|
sqlStatements << "INSERT INTO basic.model_group (model_type_id, attribute_group_id) VALUES "
|
||||||
QString::number(modelID) + "," + QString::number(groupID) + ")";*/
|
"(:modelID, :groupID)";
|
||||||
strSQL = "INSERT INTO basic.model_group (model_type_id, attribute_group_id) VALUES "
|
|
||||||
"(:modelID, :groupID)";
|
|
||||||
params.clear();
|
params.clear();
|
||||||
params.insert(":modelID", modelID);
|
params.insert(":modelID", modelID);
|
||||||
params.insert(":groupID", groupID);
|
params.insert(":groupID", groupID);
|
||||||
try
|
paramsList << params;
|
||||||
|
}
|
||||||
|
try
|
||||||
|
{
|
||||||
|
executeBatchSQL(connectionName, sqlStatements, paramsList);
|
||||||
|
}
|
||||||
|
catch (const DatabaseException& e)
|
||||||
|
{
|
||||||
|
if(!db.rollback()) // 回滚失败时记录警告
|
||||||
{
|
{
|
||||||
executeSQL(connectionName, strSQL, params);
|
LOG_ERROR("DB", QString("Rollback failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText()));
|
||||||
}
|
|
||||||
catch (const DatabaseException& e)
|
|
||||||
{
|
|
||||||
LOG_ERROR("SQL", QString::fromWCharArray(L"mapping model & group失败, modelID:%1, groupID:%2")
|
|
||||||
.arg(QString::number(modelID))
|
|
||||||
.arg(QString::number(groupID)));
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!db.commit()) // 提交
|
||||||
|
{
|
||||||
|
LOG_ERROR("DB", QString("Commit transaction failed. connectionName: %1. error: %2").arg(connectionName, db.lastError().databaseText()));
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue