C++ (Qt)#pragma once#include <QSqlDatabase>#include <QThread>#include <QMap> class ConnectionPool : public QObject{ Q_OBJECTpublic: explicit ConnectionPool(const QString driverName, const QString& dbName, const QString& dbHost, const quint16& dbPort, const QString& userName, const QString& userPassword, QObject* parent = 0); ~ConnectionPool(); QSqlDatabase getConnection(); QSqlDatabase getConnectionForThread(QThread* thread); private: QString generateConnectionName(QThread* thread) const; void onThreadDestroyed(); private: const QString _driverName; const QString _dbName; const QString _dbHost; const quint16 _dbPort; const QString _userName; const QString _userPassword; QMap<QThread*, QString> _threadConnectionNameMap; QMutex _mutex;};
C++ (Qt)#include "ConnectionPool.h"#include <QDataStream>#include <QCryptographicHash> ConnectionPool::ConnectionPool(const QString driverName, const QString& dbName, const QString& dbHost, const quint16& dbPort, const QString& userName, const QString& userPassword, QObject* parent) : QObject(parent), _driverName(driverName), _dbName(dbName), _dbHost(dbHost), _dbPort(dbPort), _userName(userName), _userPassword(userPassword){} ConnectionPool::~ConnectionPool(){ foreach (QThread* thread, _threadConnectionNameMap.keys()) { QSqlDatabase::removeDatabase(_threadConnectionNameMap.value(thread)); }} QSqlDatabase ConnectionPool::getConnection(){ return getConnectionForThread(QThread::currentThread());} QSqlDatabase ConnectionPool::getConnectionForThread(QThread* thread){ QSqlDatabase db; if(_threadConnectionNameMap.contains(thread)) { db = QSqlDatabase::database(_threadConnectionNameMap.value(thread)); } else { QMutexLocker locker(&_mutex); const QString connectionName = generateConnectionName(thread); db = QSqlDatabase::addDatabase(_driverName, connectionName); _threadConnectionNameMap.insert(thread, connectionName); connect(thread, &QThread::destroyed, this, &ConnectionPool::onThreadDestroyed); db.setDatabaseName(_dbName); db.setUserName(_userName); db.setPassword(_userPassword); db.setHostName(_dbHost); db.setPort(_dbPort); } if(!db.isOpen()) db.open(); return db;} QString ConnectionPool::generateConnectionName(QThread* thread) const{ QByteArray data; QDataStream stream(&data, QIODevice::WriteOnly); stream.setVersion(QDataStream::Qt_5_0); stream << (long)thread; stream << _driverName; stream << _dbName; stream << _dbHost; stream << _dbPort; stream << _userName; stream << _userPassword; QCryptographicHash hash(QCryptographicHash::Md5); hash.addData(data); return QString(hash.result().toHex());} void ConnectionPool::onThreadDestroyed(){ QThread* thread = static_cast<QThread*>(sender()); if(_threadConnectionNameMap.contains(thread)) { QString connectionName = _threadConnectionNameMap.take(thread); QSqlDatabase::removeDatabase(connectionName); }}
C++ (Qt)QSqlDatabase ConnectionPool::getConnectionForThread(QThread* thread){ QReadLocker rLocker(&_rwLock); if(_threadConnectionNameMap.contains(thread)) { QSqlDatabase db = QSqlDatabase::database(_threadConnectionNameMap.value(thread)); db.open(); return db; } rLocker.unlock(); QWriteLocker wLocker(&_rwLock); const QString connectionName = generateConnectionName(thread); QSqlDatabase db = QSqlDatabase::addDatabase(_driverName, connectionName); _threadConnectionNameMap.insert(thread, connectionName); connect(thread, &QThread::destroyed, this, &ConnectionPool::onThreadDestroyed); db.setDatabaseName(_dbName); db.setUserName(_userName); db.setPassword(_userPassword); db.setHostName(_dbHost); db.setPort(_dbPort); if(!db.isOpen()) db.open(); return db;}
C++ (Qt)QSqlDatabase ConnectionPool::getConnectionForThread(QThread* thread){ QMutexLocker locker(&_mutex); if(_threadConnectionNameMap.contains(thread)) { QSqlDatabase db = QSqlDatabase::database(_threadConnectionNameMap.value(thread)); db.open(); return db; } const QString connectionName = generateConnectionName(thread); QSqlDatabase db = QSqlDatabase::addDatabase(_driverName, connectionName); _threadConnectionNameMap.insert(thread, connectionName); connect(thread, &QThread::destroyed, this, &ConnectionPool::onThreadDestroyed); db.setDatabaseName(_dbName); db.setUserName(_userName); db.setPassword(_userPassword); db.setHostName(_dbHost); db.setPort(_dbPort); if(!db.isOpen()) db.open(); return db;}