#include "global.h" #include "sqlQueryExecutor.h" #include "logger.h" #include SqlQueryExecutor& SqlQueryExecutor::instance() { //采用静态局部变量的方式,静态局部变量的初始化是在第一次访问时,以后的调用不会多次初始化,并且生命周期和程序一致 static SqlQueryExecutor instance; return instance; } SqlQueryExecutor::SqlQueryExecutor() {} SqlQueryExecutor::~SqlQueryExecutor() {} //基础SQL语句执行接口 QSqlQuery SqlQueryExecutor::executeSQL(const QString& strConnectionName, const QString& strSQL, const QVariantHash& params) { QSqlDatabase db = QSqlDatabase::database(strConnectionName); if(!db.isOpen()) { LOG_ERROR("DB", QString("Database not open. connectionName: %1. error:").arg(strConnectionName)); throw DatabaseException(db.lastError()); } QSqlQuery sqlQuery(db); sqlQuery.prepare(strSQL); //绑定参数 for(auto it = params.constBegin(); it != params.constEnd(); it++) { sqlQuery.bindValue(it.key(), it.value()); } if (!sqlQuery.exec(strSQL)) { LOG_ERROR("SQL", QString("SQL '%1' execute error: %2").arg(strSQL).arg(sqlQuery.lastError().databaseText())); throw DatabaseException(sqlQuery.lastError()); } return sqlQuery; } //具体业务查询接口 const QVector SqlQueryExecutor::getModels(const QString& strConnectionName) { QVector models; QString strSQL = "SELECT id, model_type, model_name, remark FROM basic.model_type ORDER BY id ASC"; try { QSqlQuery query = executeSQL(strConnectionName, strSQL); while(query.next()) { int id = query.value(0).toInt(); QString type = query.value(1).toString(); QString name = query.value(2).toString(); QString remark = query.value(3).toString(); QVector groups = getModelGroups(strConnectionName, id); models.emplace_back(id, name, type, remark, groups); } } catch (const DatabaseException& e) { emit errorOccurred(QString::fromWCharArray(L"获取模型信息失败,详情可见日志文件")); } return models; //编译器的RVO/NRVO会自动优化、避免临时拷贝 } QVector SqlQueryExecutor::getModelGroups(const QString& strConnectionName, int modelID) { QVector groups; QString strSQL = "SELECT attribute_group_id FROM basic.mapping_model_group WHERE model_type_id = " + QString::number(modelID); try { QSqlQuery query = executeSQL(strConnectionName, strSQL); while(query.next()) { groups.append(query.value(0).toInt()); } } catch (const DatabaseException& e) { LOG_ERROR("SQL", QString::fromWCharArray(L"获取模型所含属性组名称失败,id:%1").arg(QString::number(modelID))); return groups; } return groups; } bool SqlQueryExecutor::addModel(const QString& connectionName, Model& model) { int modelID = -1; //先向model_type中插入一条记录 /*QString strSQL = "INSERT INTO basic.model_type (model_type, model_name, remark) VALUES " "(:type, :name, :remark)"; QVariantHash params; params.insert(":type", model.type); params.insert(":name", model.name); 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 { QSqlQuery query = executeSQL(connectionName, strSQL); modelID = query.lastInsertId().toInt(); //lasatInsertId()会返回最近插入行的自增id model.id = modelID; } catch (const DatabaseException& e) { return false; } //然后向mapping_model_group中插入记录 for(int groupID : model.groups) { strSQL = "INSERT INTO basic.mapping_model_group (model_type_id, attribute_group_id) VALUES (" + QString::number(modelID) + "," + QString::number(groupID) + ")"; /*strSQL = "INSERT INTO basic.mapping_model_group (model_type_id, attribute_group_id, remark) VALUES " "(:modelID, :groupID)"; params.clear(); params.insert(":modelID", modelID); params.insert(":groupID", groupID);*/ try { executeSQL(connectionName, strSQL); } 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 true; } bool SqlQueryExecutor::modelNameExistsInDB(const QString& connectionName, const QString& name) { bool exists = false; QString strSQL = "SELECT id FROM basic.model_type WHERE model_name = \'" + name + "\'"; try { QSqlQuery query = executeSQL(connectionName, strSQL); if(query.next()) exists = true; } catch (const DatabaseException& e) { exists = true; } return exists; } bool SqlQueryExecutor::modelTypeExistsInDB(const QString& connectionName, const QString& type) { bool exists = false; QString strSQL = "SELECT id FROM basic.model_type WHERE model_type = \'" + type + "\'"; try { QSqlQuery query = executeSQL(connectionName, strSQL); if(query.next()) exists = true; } catch (const DatabaseException& e) { exists = true; } return exists; } bool SqlQueryExecutor::removeMode(const QString& connectionName, int modelID) { } const QVector SqlQueryExecutor::getAttributeGroup(const QString& strConnectionName) { QVector groupList; QString strSQL = "SELECT id, group_type, group_name, remark, is_public FROM basic.attribute_group ORDER BY id ASC"; try { QSqlQuery query = executeSQL(strConnectionName, strSQL); while(query.next()) { int id = query.value(0).toInt(); QString type = query.value(1).toString(); QString name = query.value(2).toString(); QString remark = query.value(3).toString(); bool isPublic = query.value(4).toBool(); groupList.emplace_back(id,name,type,remark,isPublic); //直接调用构造函数,避免拷贝 } } catch (const DatabaseException& e) { emit errorOccurred(QString::fromWCharArray(L"获取属性组别信息失败,详情可见日志文件")); } return groupList; } const QString SqlQueryExecutor::getArributeGropuName(const QString& strConnectionName, int groupID) { QString name; QString strSQL = "SELECT group_name FROM basic.attribute_group WHERE id = " + QString::number(groupID); try { QSqlQuery query = executeSQL(strConnectionName, strSQL); if(query.next()) name = query.value(0).toString(); } catch (const DatabaseException& e) { LOG_ERROR("SQL", QString::fromWCharArray(L"获取属性组名称失败,id:%1").arg(QString::number(groupID))); name = "groupID-" + QString::number(groupID); } return name; }