在SQL语句执行函数中添加是否开启事务的功能选项

This commit is contained in:
duanshengchao 2025-03-17 14:46:52 +08:00
parent 021785d16c
commit 0aca9bd518
2 changed files with 73 additions and 24 deletions

View File

@ -13,7 +13,7 @@ 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 = {}); QSqlQuery executeSQL(const QString& strConnectionName, const QString& strSQL, const QVariantHash& params = {}, 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&);

View File

@ -16,28 +16,67 @@ SqlQueryExecutor::~SqlQueryExecutor()
{} {}
//基础SQL语句执行接口 //基础SQL语句执行接口
QSqlQuery SqlQueryExecutor::executeSQL(const QString& strConnectionName, const QString& strSQL, const QVariantHash& params) QSqlQuery SqlQueryExecutor::executeSQL(const QString& strConnectionName, const QString& strSQL, const QVariantHash& params, bool useTranscation)
{ {
QSqlDatabase db = QSqlDatabase::database(strConnectionName); QSqlDatabase db = QSqlDatabase::database(strConnectionName);
if(!db.isOpen()) if(!db.isOpen())
{ {
LOG_ERROR("DB", QString("Database not open. connectionName: %1. error:").arg(strConnectionName)); LOG_ERROR("DB", QString("Database not open. connectionName: %1").arg(strConnectionName));
throw DatabaseException(db.lastError()); throw DatabaseException(db.lastError());
} }
//事务
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 sqlQuery(db); QSqlQuery sqlQuery(db);
sqlQuery.prepare(strSQL); try
//绑定参数
for(auto it = params.constBegin(); it != params.constEnd(); it++)
{ {
sqlQuery.bindValue(it.key(), it.value()); 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());
}
// 提交事务(如果已开启)
if(transactionStarted && !db.commit())
{
throw DatabaseException(db.lastError());
LOG_ERROR("DB", QString("Commit transaction failed. connectionName: %1. error: %2").arg(strConnectionName, db.lastError().databaseText()));
}
} }
if (!sqlQuery.exec(strSQL)) catch (const DatabaseException& e)
{ {
LOG_ERROR("SQL", QString("SQL '%1' execute error: %2").arg(strSQL).arg(sqlQuery.lastError().databaseText())); // 错误处理:回滚事务(如果已开启)
throw DatabaseException(sqlQuery.lastError()); if(transactionStarted)
{
if(!db.rollback()) // 回滚失败时记录警告
{
LOG_ERROR("DB", QString("Rollback failed. connectionName: %1. error: %2").arg(strConnectionName, db.lastError().databaseText()));
}
}
throw; // 重新抛出异常
} }
return sqlQuery; return sqlQuery;
} }
@ -68,7 +107,7 @@ const QVector<Model> SqlQueryExecutor::getModels(const QString& strConnectionNam
QVector<int> SqlQueryExecutor::getModelGroups(const QString& strConnectionName, int modelID) QVector<int> SqlQueryExecutor::getModelGroups(const QString& strConnectionName, int modelID)
{ {
QVector<int> groups; QVector<int> groups;
QString strSQL = "SELECT attribute_group_id FROM basic.mapping_model_group WHERE model_type_id = " + QString::number(modelID); QString strSQL = "SELECT attribute_group_id FROM basic.model_group WHERE model_type_id = " + QString::number(modelID);
try try
{ {
QSqlQuery query = executeSQL(strConnectionName, strSQL); QSqlQuery query = executeSQL(strConnectionName, strSQL);
@ -89,18 +128,17 @@ bool SqlQueryExecutor::addModel(const QString& connectionName, Model& model)
{ {
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 "
"(:type, :name, :remark)"; "(:type, :name, :remark)";
QVariantHash params; QVariantHash params;
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 (\'" +
QString strSQL = "INSERT INTO basic.model_type (model_type, model_name, remark) VALUES (\'" + model.type + "\',\'" + model.name + + "\',\'" + model.remark +"\')";*/
model.type + "\',\'" + model.name + + "\',\'" + model.remark +"\')";
try try
{ {
QSqlQuery query = executeSQL(connectionName, strSQL); QSqlQuery query = executeSQL(connectionName, strSQL, params);
modelID = query.lastInsertId().toInt(); //lasatInsertId()会返回最近插入行的自增id modelID = query.lastInsertId().toInt(); //lasatInsertId()会返回最近插入行的自增id
model.id = modelID; model.id = modelID;
} }
@ -109,19 +147,19 @@ bool SqlQueryExecutor::addModel(const QString& connectionName, Model& model)
return false; return false;
} }
//然后向mapping_model_group中插入记录 //然后向model_group中插入记录
for(int groupID : model.groups) for(int groupID : model.groups)
{ {
strSQL = "INSERT INTO basic.mapping_model_group (model_type_id, attribute_group_id) VALUES (" + /*strSQL = "INSERT INTO basic.model_group (model_type_id, attribute_group_id) VALUES (" +
QString::number(modelID) + "," + QString::number(groupID) + ")"; QString::number(modelID) + "," + QString::number(groupID) + ")";*/
/*strSQL = "INSERT INTO basic.mapping_model_group (model_type_id, attribute_group_id, remark) VALUES " strSQL = "INSERT INTO basic.model_group (model_type_id, attribute_group_id) VALUES "
"(:modelID, :groupID)"; "(:modelID, :groupID)";
params.clear(); params.clear();
params.insert(":modelID", modelID); params.insert(":modelID", modelID);
params.insert(":groupID", groupID);*/ params.insert(":groupID", groupID);
try try
{ {
executeSQL(connectionName, strSQL); executeSQL(connectionName, strSQL, params);
} }
catch (const DatabaseException& e) catch (const DatabaseException& e)
{ {
@ -171,7 +209,18 @@ bool SqlQueryExecutor::modelTypeExistsInDB(const QString& connectionName, const
bool SqlQueryExecutor::removeMode(const QString& connectionName, int modelID) bool SqlQueryExecutor::removeMode(const QString& connectionName, int modelID)
{ {
QString strSQL = "DELETE FROM basic.model_type WHERE id = :id"/* + QString::number(modelID)*/;
QVariantHash params;
params.insert(":id", modelID);
try
{
executeSQL(connectionName, strSQL, params, true);
}
catch (const DatabaseException& e)
{
return false;
}
return true;
} }
const QVector<AttributeGroup> SqlQueryExecutor::getAttributeGroup(const QString& strConnectionName) const QVector<AttributeGroup> SqlQueryExecutor::getAttributeGroup(const QString& strConnectionName)