#include "CdbConnectionPool.h" #include "utils/SettingConfig.h" /*-----------------------------------------------------------------------------| | CDbConnectionPoolPrivate 的定义 | |----------------------------------------------------------------------------*/ class CDbConnectionPoolPrivate { public: CDbConnectionPoolPrivate(); // 数据库信息 QString databaseTypeLocal; QString hostNameLocal; QString databaseNameLocal; QString usernameLocal; QString passwordLocal; int portLocal; QString databaseTypeRemote; QString hostNameRemote; QString databaseNameRemote; QString usernameRemote; QString passwordRemote; bool testOnBorrow; // 取得连接的时候验证连接有效 QString testOnBorrowSql; // 测试访问数据库的 SQL }; CDbConnectionPoolPrivate::CDbConnectionPoolPrivate() { // 可以从配置文件里读取 ---- 这里直接给出,记得修改!!! testOnBorrow = true; testOnBorrowSql = "SELECT 1"; // MYSQL 直连 //databaseTypeLocal = "QMYSQL"; databaseTypeLocal = SettingConfig::getInstance().LOCAL_Mode; hostNameLocal = SettingConfig::getInstance().LOCAL_HOST; databaseNameLocal = SettingConfig::getInstance().LOCAL_ODBC_NAME; usernameLocal = SettingConfig::getInstance().LOCAL_USERNAME; passwordLocal = SettingConfig::getInstance().LOCAL_PASSWORD; portLocal = SettingConfig::getInstance().LOCAL_PORT.toInt(); databaseTypeRemote = "QODBC"; hostNameRemote = SettingConfig::getInstance().REMOTE_HOST; databaseNameRemote = SettingConfig::getInstance().REMOTE_ODBC_NAME; usernameRemote = SettingConfig::getInstance().REMOTE_USERNAME; passwordRemote = SettingConfig::getInstance().REMOTE_PASSWORD; } /*-----------------------------------------------------------------------------| | CDbConnectionPool 的定义 | |----------------------------------------------------------------------------*/ CDbConnectionPool::CDbConnectionPool() : d(new CDbConnectionPoolPrivate) { } CDbConnectionPool::~CDbConnectionPool() { delete d; } QSqlDatabase CDbConnectionPool::openConnection() { QSqlDatabase db = QSqlDatabase::addDatabase(d->databaseTypeLocal); db.setHostName(d->hostNameLocal); db.setDatabaseName(d->databaseNameLocal); db.setUserName(d->usernameLocal); db.setPassword(d->passwordLocal); db.setPort(d->portLocal); if (db.open()) { qDebug().noquote() << QString("QMYSQL Connection created"); return db; } else { qDebug().noquote() << "Create connection error:" << db.lastError().text(); return QSqlDatabase(); } } // 获取数据库连接 QSqlDatabase CDbConnectionPool::openConnection(const QString type, const QString &connectionName) { // 1. 创建连接的全名: 基于线程的地址和传入进来的 connectionName,因为同一个线程可能申请创建多个数据库连接 // 2. 如果连接已经存在,复用它,而不是重新创建 // 2.1 返回连接前访问数据库,如果连接断开,可以重新建立连接 (测试: 关闭数据库几分钟后再启动,再次访问数据库) // 3. 如果连接不存在,则创建连接 // 4. 线程结束时,释放在此线程中创建的数据库连接 // [1] 创建连接的全名: 基于线程的地址和传入进来的 connectionName,因为同一个线程可能申请创建多个数据库连接 QString baseConnectionName = type + "_conn_" + QString::number(quint64(QThread::currentThread()), 16); QString fullConnectionName = baseConnectionName + connectionName; if (QSqlDatabase::contains(fullConnectionName)) { // [2] 如果连接已经存在,复用它,而不是重新创建 QSqlDatabase existingDb = QSqlDatabase::database(fullConnectionName); if (d->testOnBorrow) { // [2.1] 返回连接前访问数据库,如果连接断开,可以重新建立连接 (测试: 关闭数据库几分钟后再启动,再次访问数据库) // qDebug().noquote() << QString("Test connection on borrow, execute: %1, for connection %2").arg(d->testOnBorrowSql).arg(fullConnectionName); QSqlQuery query(d->testOnBorrowSql, existingDb); if (query.lastError().type() != QSqlError::NoError && !existingDb.open()) { qDebug().noquote() << "Open datatabase error:" << existingDb.lastError().text(); return QSqlDatabase(); } } return existingDb; } else { // [3] 如果连接不存在,则创建连接 if (qApp != nullptr) { // [4] 线程结束时,释放在此线程中创建的数据库连接 QObject::connect(QThread::currentThread(), &QThread::finished, qApp, [fullConnectionName]() { if (QSqlDatabase::contains(fullConnectionName)) { QSqlDatabase::removeDatabase(fullConnectionName); qDebug().noquote() << QString("Connection deleted: %1").arg(fullConnectionName); } }); } return createConnection(type.toUpper(), fullConnectionName); } } // 创建数据库连接 QSqlDatabase CDbConnectionPool::createConnection(const QString type, const QString &connectionName) { static int sn = 0; // 创建一个新的数据库连接 QSqlDatabase db; if (type == "LOCAL") { db = QSqlDatabase::addDatabase(d->databaseTypeLocal, connectionName); db.setHostName(d->hostNameLocal); db.setDatabaseName(d->databaseNameLocal); db.setUserName(d->usernameLocal); db.setPassword(d->passwordLocal); db.setPort(d->portLocal); } else if (type == "REMOTE") { db = QSqlDatabase::addDatabase(d->databaseTypeRemote, connectionName); db.setHostName(d->hostNameRemote); db.setDatabaseName(d->databaseNameRemote); db.setUserName(d->usernameRemote); db.setPassword(d->passwordRemote); } if (db.open()) { qDebug().noquote() << QString("Connection created: %1, sn: %2").arg(connectionName).arg(++sn); return db; } else { qDebug().noquote() << "Create connection error:" << db.lastError().text(); return QSqlDatabase(); } }