├── .gitignore ├── LICENSE ├── NDBPool.pro ├── NDBPool ├── NDBPool.pro ├── NDBPool.pro.user ├── NDBPool_inc.pri ├── NDBPool_resource.rc ├── NDBPool_src.pri ├── inc │ ├── ndbpool.h │ ├── ndbpool_global.h │ └── ndbpool_p.h └── src │ ├── ndbpool.cpp │ └── ndbpool_p.cpp ├── README.md ├── _config.yml ├── example ├── example.pro ├── main.cpp ├── manifest.xml ├── testconnection.cpp ├── testconnection.h ├── threadtest.cpp └── threadtest.h └── scripts ├── clear.bat ├── pro_arch.png └── 系统架构.bmpr /.gitignore: -------------------------------------------------------------------------------- 1 | /NDBPool.pro.user 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 daodaoliang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /NDBPool.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by daodaoliang 2016-07-11T11:08:28 4 | # 5 | #------------------------------------------------- 6 | 7 | TEMPLATE = subdirs 8 | CONFIG += ordered 9 | SUBDIRS += \ 10 | ./NDBPool \ 11 | example 12 | -------------------------------------------------------------------------------- /NDBPool/NDBPool.pro: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by daodaoliang 2016-07-11T11:08:28 4 | # 5 | #------------------------------------------------- 6 | 7 | QT += sql 8 | QT -= gui 9 | TARGET = NDBPool 10 | TEMPLATE = lib 11 | DEFINES += NDBPOOL_LIBRARY 12 | CONFIG += c++11 13 | 14 | # 版本号 15 | win32{ 16 | RC_FILE += ./NDBPool_resource.rc 17 | } 18 | unix{ 19 | VERSION = 1.0.7 20 | } 21 | 22 | # 源码 23 | include(./NDBPool_src.pri) 24 | INCLUDEPATH += ./inc/ \ 25 | 26 | # 输出定义 27 | win32{ 28 | CONFIG += debug_and_release 29 | CONFIG(release, debug|release) { 30 | target_path = ./build_/dist 31 | } else { 32 | target_path = ./build_/debug 33 | } 34 | DESTDIR = ../bin 35 | MOC_DIR = $$target_path/moc 36 | RCC_DIR = $$target_path/rcc 37 | OBJECTS_DIR = $$target_path/obj 38 | } 39 | 40 | unix{ 41 | CONFIG += debug_and_release 42 | CONFIG(release, debug|release) { 43 | target_path = ./build_/dist 44 | } else { 45 | target_path = ./build_/debug 46 | } 47 | DESTDIR = ../bin 48 | MOC_DIR = $$target_path/moc 49 | RCC_DIR = $$target_path/rcc 50 | OBJECTS_DIR = $$target_path/obj 51 | } 52 | 53 | # 打印信息 54 | message(Qt version: $$[QT_VERSION]) 55 | message(Qt is installed in $$[QT_INSTALL_PREFIX]) 56 | message(the NDBPool will create in folder: $$target_path) 57 | -------------------------------------------------------------------------------- /NDBPool/NDBPool.pro.user: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | EnvironmentId 7 | {990330d9-c6c4-4fd5-a136-73d4a873e313} 8 | 9 | 10 | ProjectExplorer.Project.ActiveTarget 11 | 0 12 | 13 | 14 | ProjectExplorer.Project.EditorSettings 15 | 16 | true 17 | false 18 | true 19 | 20 | Cpp 21 | 22 | CppGlobal 23 | 24 | 25 | 26 | QmlJS 27 | 28 | QmlJSGlobal 29 | 30 | 31 | 2 32 | UTF-8 33 | false 34 | 4 35 | true 36 | 80 37 | true 38 | true 39 | 1 40 | true 41 | false 42 | 0 43 | true 44 | 0 45 | 8 46 | false 47 | 1 48 | true 49 | true 50 | true 51 | false 52 | 53 | 54 | 55 | ProjectExplorer.Project.PluginSettings 56 | 57 | 58 | 59 | ProjectExplorer.Project.Target.0 60 | 61 | Desktop Qt 5.6.0 MinGW 32bit 62 | Desktop Qt 5.6.0 MinGW 32bit 63 | qt.56.win32_mingw49_kit 64 | 0 65 | 0 66 | 0 67 | 68 | E:/NDBPool 69 | 70 | 71 | true 72 | qmake 73 | 74 | QtProjectManager.QMakeBuildStep 75 | true 76 | 77 | false 78 | false 79 | false 80 | 81 | 82 | true 83 | Make 84 | 85 | Qt4ProjectManager.MakeStep 86 | 87 | false 88 | 89 | 90 | 91 | 2 92 | 构建 93 | 94 | ProjectExplorer.BuildSteps.Build 95 | 96 | 97 | 98 | true 99 | Make 100 | 101 | Qt4ProjectManager.MakeStep 102 | 103 | true 104 | clean 105 | 106 | 107 | 108 | true 109 | 110 | E:/NDBPool/scripts/clear.bat 111 | %{buildDir} 112 | 自定义进程步骤 113 | 114 | ProjectExplorer.ProcessStep 115 | 116 | 2 117 | 清理 118 | 119 | ProjectExplorer.BuildSteps.Clean 120 | 121 | 2 122 | false 123 | 124 | Debug 125 | 126 | Qt4ProjectManager.Qt4BuildConfiguration 127 | 2 128 | true 129 | 130 | 131 | E:/NDBPool 132 | 133 | 134 | true 135 | qmake 136 | 137 | QtProjectManager.QMakeBuildStep 138 | false 139 | 140 | false 141 | false 142 | false 143 | 144 | 145 | true 146 | Make 147 | 148 | Qt4ProjectManager.MakeStep 149 | 150 | false 151 | 152 | 153 | 154 | 2 155 | 构建 156 | 157 | ProjectExplorer.BuildSteps.Build 158 | 159 | 160 | 161 | true 162 | Make 163 | 164 | Qt4ProjectManager.MakeStep 165 | 166 | true 167 | clean 168 | 169 | 170 | 1 171 | 清理 172 | 173 | ProjectExplorer.BuildSteps.Clean 174 | 175 | 2 176 | false 177 | 178 | Release 179 | 180 | Qt4ProjectManager.Qt4BuildConfiguration 181 | 0 182 | true 183 | 184 | 185 | E:/build-NDBPool-Desktop_Qt_5_6_0_MinGW_32bit-Profile 186 | 187 | 188 | true 189 | qmake 190 | 191 | QtProjectManager.QMakeBuildStep 192 | true 193 | 194 | false 195 | true 196 | false 197 | 198 | 199 | true 200 | Make 201 | 202 | Qt4ProjectManager.MakeStep 203 | 204 | false 205 | 206 | 207 | 208 | 2 209 | 构建 210 | 211 | ProjectExplorer.BuildSteps.Build 212 | 213 | 214 | 215 | true 216 | Make 217 | 218 | Qt4ProjectManager.MakeStep 219 | 220 | true 221 | clean 222 | 223 | 224 | 1 225 | 清理 226 | 227 | ProjectExplorer.BuildSteps.Clean 228 | 229 | 2 230 | false 231 | 232 | Profile 233 | 234 | Qt4ProjectManager.Qt4BuildConfiguration 235 | 0 236 | true 237 | 238 | 3 239 | 240 | 241 | 0 242 | 部署 243 | 244 | ProjectExplorer.BuildSteps.Deploy 245 | 246 | 1 247 | 在本地部署 248 | 249 | ProjectExplorer.DefaultDeployConfiguration 250 | 251 | 1 252 | 253 | 254 | false 255 | 1000 256 | 257 | true 258 | 259 | false 260 | false 261 | false 262 | false 263 | true 264 | 0.01 265 | 10 266 | true 267 | 1 268 | 25 269 | 270 | 1 271 | true 272 | false 273 | true 274 | valgrind 275 | 276 | 0 277 | 1 278 | 2 279 | 3 280 | 4 281 | 5 282 | 6 283 | 7 284 | 8 285 | 9 286 | 10 287 | 11 288 | 12 289 | 13 290 | 14 291 | 292 | 2 293 | 294 | 295 | 296 | %{buildDir} 297 | 自定义执行档 298 | 299 | ProjectExplorer.CustomExecutableRunConfiguration 300 | 3768 301 | false 302 | true 303 | false 304 | false 305 | true 306 | 307 | 1 308 | 309 | 310 | 311 | ProjectExplorer.Project.TargetCount 312 | 1 313 | 314 | 315 | ProjectExplorer.Project.Updater.FileVersion 316 | 18 317 | 318 | 319 | Version 320 | 18 321 | 322 | 323 | -------------------------------------------------------------------------------- /NDBPool/NDBPool_inc.pri: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by daodaoliang 2016-07-11T11:08:28 4 | # 5 | #------------------------------------------------- 6 | 7 | INCLUDEPATH += $$PWD\inc 8 | 9 | win32{ 10 | LIBS += -L$$PWD/../bin/ -lNDBPool 11 | DEPENDPATH += $$PWD/../bin 12 | } 13 | 14 | unix{ 15 | LIBS += -L$$PWD/../bin/ -lNDBPool 16 | DEPENDPATH += $$PWD/../bin 17 | } 18 | 19 | 20 | -------------------------------------------------------------------------------- /NDBPool/NDBPool_resource.rc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daodaoliang/NDBPool/cb4d836fcb07cf52d0700a38ee9467eec200c025/NDBPool/NDBPool_resource.rc -------------------------------------------------------------------------------- /NDBPool/NDBPool_src.pri: -------------------------------------------------------------------------------- 1 | #------------------------------------------------- 2 | # 3 | # Project created by daodaoliang 2016-07-11T11:08:28 4 | # 5 | #------------------------------------------------- 6 | 7 | SOURCES += $$PWD\src\ndbpool.cpp\ 8 | $$PWD\src\ndbpool_p.cpp 9 | 10 | HEADERS += $$PWD\inc\ndbpool_global.h\ 11 | $$PWD\inc\ndbpool.h\ 12 | $$PWD\inc\ndbpool_p.h 13 | -------------------------------------------------------------------------------- /NDBPool/inc/ndbpool.h: -------------------------------------------------------------------------------- 1 | #ifndef NDBPOOL_H 2 | #define NDBPOOL_H 3 | /** 4 | * 作者: daodaoliang 5 | * 时间: 2016年8月5日 6 | * 版本: 1.0.7.0 7 | * 邮箱: daodaoliang@yeah.net 8 | */ 9 | #include "ndbpool_global.h" 10 | #include "ndbpool_p.h" 11 | #include 12 | #include 13 | 14 | struct connectActive{ 15 | qint64 lastActiveTime; 16 | QString poolName; 17 | bool longConnect; 18 | }; 19 | 20 | /** 21 | * @brief The NDBPool class 22 | * 数据库连接池库的接口文档 23 | */ 24 | 25 | class NDBPOOLSHARED_EXPORT NDBPool: public QObject 26 | { 27 | Q_OBJECT 28 | public: 29 | /** 30 | * @brief release 释放所有链接 31 | * @return void 32 | */ 33 | static void release(); 34 | 35 | /** 36 | * @brief getNewConnection getNewConnection 获取一个可用的连接链接 37 | * @param paramHostName 主机名 38 | * @param paramDatabaseName 数据库名字 39 | * @param paramUserName 数据库名字 40 | * @param paramPassword 数据库密码 41 | * @param paramPort 数据库端口 42 | * @param longConnect 是否为长连接 43 | * @param longConnnectName 长连接名字 44 | * @return 45 | */ 46 | static QSqlDatabase getNewConnection(QString paramHostName, 47 | QString paramDatabaseName, 48 | QString paramUserName, 49 | QString paramPassword, 50 | int paramPort, 51 | bool longConnect=false, 52 | QString longConnnectName=""); 53 | 54 | /** 55 | * @brief closeConnection 释放本地连接 56 | * @param connection 57 | */ 58 | static void closeConnection(const QSqlDatabase &connection); 59 | 60 | public: 61 | /** 62 | * @brief NDBPool 构造函数 63 | * @param paramIsDebug 是否是调试模式 64 | */ 65 | NDBPool(bool paramIsDebug = true,QObject * parent = 0); 66 | 67 | ~NDBPool(); 68 | 69 | private slots: 70 | 71 | /** 72 | * @brief slots_forceBreak 强制断开连接 73 | */ 74 | void slots_forceBreak(); 75 | 76 | private: 77 | /** 78 | * @brief instance 单例实例 79 | * @param paramIsDebug 是否是调试模式 80 | * @return 81 | */ 82 | static NDBPool& instance(bool paramIsDebug = true); 83 | 84 | private: 85 | 86 | /** 87 | * @brief checkForceBreakInterval 强制断开连接的检查频率 88 | */ 89 | short checkForceBreakInterval; 90 | 91 | /** 92 | * @brief connectionLastActiveTimeMap 连接的最近状态映射 93 | */ 94 | static QMap connectionLastActiveTimeMap; 95 | 96 | /** 97 | * @brief poolMap 数据库连接池名字和连接池的映射 98 | */ 99 | static QMap poolMap; 100 | 101 | /** 102 | * @brief mLock 103 | */ 104 | static QMutex mLock; 105 | 106 | /** 107 | * @brief forceBreakTime 强制断开连接的判定时间差 108 | */ 109 | int forceBreakTime; 110 | 111 | /** 112 | * @brief isDebug 是否为调试模式 113 | */ 114 | static bool isDebug; 115 | 116 | /** 117 | * @brief activeTimer 维持活跃连接 118 | */ 119 | QTimer activeTimer; 120 | 121 | /** 122 | * @brief checkDeadTimer 检测死链接 123 | */ 124 | QTimer checkDeadTimer; 125 | 126 | /** 127 | * @brief forceBreakTimer 检查超时链接 128 | */ 129 | QTimer forceBreakTimer; 130 | }; 131 | 132 | #endif // NDBPOOL_H 133 | -------------------------------------------------------------------------------- /NDBPool/inc/ndbpool_global.h: -------------------------------------------------------------------------------- 1 | #ifndef NDBPOOL_GLOBAL_H 2 | #define NDBPOOL_GLOBAL_H 3 | 4 | #include 5 | 6 | #if defined(NDBPOOL_LIBRARY) 7 | # define NDBPOOLSHARED_EXPORT Q_DECL_EXPORT 8 | #else 9 | # define NDBPOOLSHARED_EXPORT Q_DECL_IMPORT 10 | #endif 11 | 12 | #endif // NDBPOOL_GLOBAL_H 13 | -------------------------------------------------------------------------------- /NDBPool/inc/ndbpool_p.h: -------------------------------------------------------------------------------- 1 | #ifndef NDBPOOL_P_H 2 | #define NDBPOOL_P_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | class NDBPool_p: public QObject 18 | { 19 | public: 20 | NDBPool_p(QObject *parent=0, bool paramDebug=true); 21 | ~NDBPool_p(); 22 | 23 | public: 24 | /** 25 | * @brief getNewConnection 获取一个数据库连接(名字存在则复用,不存在则创建) 26 | * @param paramConnectionName 连接名字 27 | * @return 数据库连接实例 28 | */ 29 | QSqlDatabase getNewConnection(const QString ¶mConnectionName); 30 | 31 | /** 32 | * @brief closeConnection 关闭数据库连接 33 | * @param paramConnectionName 连接名字 34 | * @return 35 | */ 36 | bool closeConnection(const QString ¶mConnectionName); 37 | 38 | /** 39 | * @brief getHostName 数据主机地址的属性获取 40 | * @return 41 | */ 42 | QString getHostName() const; 43 | 44 | /** 45 | * @brief setHostName 数据主机地址的设置 46 | * @param value 数据主机地址 47 | */ 48 | void setHostName(const QString &value); 49 | 50 | /** 51 | * @brief getDatabaseName 数据库名字的属性获取 52 | * @return 53 | */ 54 | QString getDatabaseName() const; 55 | 56 | /** 57 | * @brief setDatabaseName 数据库名字的属性设置 58 | * @param value 数据库的名字 59 | */ 60 | void setDatabaseName(const QString &value); 61 | 62 | /** 63 | * @brief getUsername 登录用户名的属性获取 64 | * @return 65 | */ 66 | QString getUsername() const; 67 | 68 | /** 69 | * @brief setUsername 登录用户名的属性设置 70 | * @param value 用户名字 71 | */ 72 | void setUsername(const QString &value); 73 | 74 | /** 75 | * @brief getPassword 登录密码的属性获取 76 | * @return 77 | */ 78 | QString getPassword() const; 79 | 80 | /** 81 | * @brief setPassword 登录密码的属性的设置 82 | * @param value 登录密码 83 | */ 84 | void setPassword(const QString &value); 85 | 86 | /** 87 | * @brief getPort 端口号的属性的获取 88 | * @return 89 | */ 90 | int getPort() const; 91 | 92 | /** 93 | * @brief setPort 端口号的属性的设置 94 | * @param value 端口号 95 | */ 96 | void setPort(int value); 97 | 98 | /** 99 | * @brief getMaxConnectionCount 最大连接数的属性的获取 100 | * @return 101 | */ 102 | int getMaxConnectionCount() const; 103 | 104 | /** 105 | * @brief setMaxConnectionCount 最大连接数的属性的设置 106 | * @param value 最大连接数 107 | */ 108 | void setMaxConnectionCount(int value); 109 | 110 | /** 111 | * @brief getMaxWaitTime 最大连接等待时间的属性的获取 112 | * @return 113 | */ 114 | int getMaxWaitTime() const; 115 | 116 | /** 117 | * @brief setMaxWaitTime 最大连接等待时间的属性的设置 118 | * @param value 最大连接等待时间 119 | */ 120 | void setMaxWaitTime(int value); 121 | 122 | public: 123 | /** 124 | * @brief usedConnectionName 处于链接中的连接名 125 | */ 126 | QStack usedConnectionName; 127 | 128 | /** 129 | * @brief unuseConnectionName 处于连接状态但是未被使用的短连接名 130 | */ 131 | QStack unusedConnectionName; 132 | 133 | /** 134 | * @brief mutex 互斥锁 135 | */ 136 | static QMutex mutex; 137 | 138 | /** 139 | * @brief semaphore 互斥计数 140 | */ 141 | QSemaphore semaphore; 142 | 143 | private: 144 | 145 | /** 146 | * @brief hostName 数据库主机地址 147 | */ 148 | QString hostName; 149 | 150 | /** 151 | * @brief databaseName 数据库名字 152 | */ 153 | QString databaseName; 154 | 155 | /** 156 | * @brief username 登录用户名 157 | */ 158 | QString username; 159 | 160 | /** 161 | * @brief password 登录密码 162 | */ 163 | QString password; 164 | 165 | /** 166 | * @brief port 数据库端口 167 | */ 168 | int port; 169 | 170 | /** 171 | * @brief maxConnectionCount 最大连接数 172 | */ 173 | int maxConnectionCount; 174 | 175 | /** 176 | * @brief maxWaitTime 最大连接等待时间 177 | */ 178 | int maxWaitTime; 179 | 180 | /** 181 | * @brief isDebug 程序运行级别 182 | */ 183 | bool isDebug; 184 | 185 | /** 186 | * @brief testSql 测试连接通畅的语句 187 | */ 188 | QString testSql; 189 | }; 190 | 191 | #endif // NDBPOOL_P_H 192 | -------------------------------------------------------------------------------- /NDBPool/src/ndbpool.cpp: -------------------------------------------------------------------------------- 1 | #include "ndbpool.h" 2 | 3 | QMap NDBPool::poolMap; 4 | bool NDBPool::isDebug; 5 | QMap NDBPool::connectionLastActiveTimeMap; 6 | QMutex NDBPool::mLock; 7 | 8 | void NDBPool::release() 9 | { 10 | QMutexLocker locker(&(NDBPool::mLock)); 11 | foreach (QString hostName, poolMap.keys()) { 12 | NDBPool_p * tempDBPool = poolMap.value(hostName); 13 | if(tempDBPool){ 14 | delete tempDBPool; 15 | tempDBPool = NULL; 16 | } 17 | } 18 | } 19 | 20 | QSqlDatabase NDBPool::getNewConnection(QString paramHostName, QString paramDatabaseName, QString paramUserName, QString paramPassword, int paramPort, bool longConnect, QString longConnnectName) 21 | { 22 | connectActive tempItem; 23 | tempItem.poolName = paramHostName; 24 | // 选择连接池 25 | if(poolMap.contains(paramHostName)){ 26 | NDBPool_p * dbConnectPtr = NDBPool::instance().poolMap.value(paramHostName); 27 | // 尝试获取一个连接 28 | if(dbConnectPtr->semaphore.tryAcquire(1, dbConnectPtr->getMaxWaitTime())){ 29 | NDBPool::mLock.lock(); 30 | // 依据长短连接从连接池中获取 31 | if(longConnect){ 32 | // 长连接 33 | QSqlDatabase innerDB = dbConnectPtr->getNewConnection(longConnnectName); 34 | tempItem.lastActiveTime = QDateTime::currentMSecsSinceEpoch(); 35 | tempItem.longConnect = true; 36 | connectionLastActiveTimeMap.insert(longConnnectName, tempItem); 37 | NDBPool::mLock.unlock(); 38 | if(!innerDB.isOpen()){ 39 | NDBPool::mLock.lock(); 40 | if(isDebug){ 41 | qDebug()<<"long connection:"<semaphore.release(); 44 | NDBPool::mLock.unlock(); 45 | return QSqlDatabase(); 46 | } else { 47 | NDBPool::mLock.lock(); 48 | if(!dbConnectPtr->usedConnectionName.contains(longConnnectName)) 49 | dbConnectPtr->usedConnectionName.push(longConnnectName); 50 | dbConnectPtr->semaphore.release(); 51 | NDBPool::mLock.unlock(); 52 | return innerDB; 53 | } 54 | } else { 55 | // 短连接 56 | QString tempConnectionName = dbConnectPtr->unusedConnectionName.length()>0 ? dbConnectPtr->unusedConnectionName.pop() : QUuid::createUuid().toString(); 57 | QSqlDatabase innerDB = dbConnectPtr->getNewConnection(tempConnectionName); 58 | tempItem.lastActiveTime = QDateTime::currentMSecsSinceEpoch(); 59 | tempItem.longConnect = false; 60 | connectionLastActiveTimeMap.insert(tempConnectionName, tempItem); 61 | NDBPool::mLock.unlock(); 62 | if(!innerDB.isOpen()){ 63 | NDBPool::mLock.lock(); 64 | dbConnectPtr->semaphore.release(); 65 | if(isDebug){ 66 | qDebug()<<"short connection:"<usedConnectionName.push(tempConnectionName); 73 | NDBPool::mLock.unlock(); 74 | return innerDB; 75 | } 76 | } 77 | 78 | } else { 79 | if(isDebug){ 80 | qDebug() << "Time out to create connection."; 81 | } 82 | return QSqlDatabase(); 83 | } 84 | } else { 85 | // 链接池不存在则创建并使用连接池 86 | NDBPool::mLock.lock(); 87 | NDBPool_p * tempPool = new NDBPool_p(); 88 | poolMap.insert(paramHostName, tempPool); 89 | tempPool->setHostName(paramHostName); 90 | tempPool->setDatabaseName(paramDatabaseName); 91 | tempPool->setUsername(paramUserName); 92 | tempPool->setPassword(paramPassword); 93 | tempPool->setPort(paramPort); 94 | NDBPool::mLock.unlock(); 95 | return getNewConnection(paramHostName,paramDatabaseName,paramUserName,paramPassword,paramPort,longConnect,longConnnectName); 96 | } 97 | } 98 | 99 | void NDBPool::closeConnection(const QSqlDatabase &connection) 100 | { 101 | QMutexLocker locker(&(NDBPool::mLock)); 102 | bool tempFlag = false; 103 | bool longConnenct = false; 104 | QString tempConnectionName = connection.connectionName(); 105 | foreach (QString hostName, poolMap.keys()) { 106 | NDBPool_p * tempPool = poolMap.value(hostName); 107 | if(tempPool->usedConnectionName.contains(tempConnectionName)){ 108 | // 长连接关闭连接 109 | if(connectionLastActiveTimeMap[tempConnectionName].longConnect){ 110 | tempPool->closeConnection(tempConnectionName); 111 | connectionLastActiveTimeMap.remove(tempConnectionName); 112 | longConnenct = true; 113 | } else { 114 | tempPool->unusedConnectionName.push(tempConnectionName); 115 | } 116 | tempPool->usedConnectionName.removeOne(tempConnectionName); 117 | tempFlag = true; 118 | tempPool->semaphore.release(); 119 | } 120 | } 121 | if(isDebug && tempFlag){ 122 | if(longConnenct){ 123 | qDebug()<= forceBreakTime){ 170 | if(tempConnection->usedConnectionName.contains(connectionName)){ 171 | tempConnection->usedConnectionName.removeOne(connectionName); 172 | tempConnection->unusedConnectionName.push(connectionName); 173 | } 174 | if(tempConnection->unusedConnectionName.contains(connectionName)){ 175 | tempConnection->unusedConnectionName.removeOne(connectionName); 176 | tempConnection->closeConnection(connectionName); 177 | } 178 | connectionLastActiveTimeMap.remove(connectionName); 179 | } 180 | use_count = tempConnection->usedConnectionName.count(); 181 | unuse_count = tempConnection->unusedConnectionName.count(); 182 | } 183 | if(isDebug){ 184 | qDebug()<<"使用中连接总数:"< 2 | #include "ndbpool.h" 3 | #include 4 | #include "threadtest.h" 5 | int main(int argc, char *argv[]) 6 | { 7 | QCoreApplication a(argc, argv); 8 | 9 | qDebug() << "/**************************开始测试用例**************************/"; 10 | { 11 | // get new short connection 12 | QSqlDatabase tempDB = NDBPool::getNewConnection("127.0.0.1","test","root","",3306); 13 | qDebug() << " connection name:" << tempDB.connectionName() << "is vaild:" << tempDB.isOpen() << "\n"; 14 | QSqlDatabase tempDB1 = NDBPool::getNewConnection("127.0.0.1","test","root","",3306); 15 | qDebug() << " connection name:" << tempDB1.connectionName() << "is vaild:" << tempDB1.isOpen() <<"\n"; 16 | QSqlDatabase tempDB2 = NDBPool::getNewConnection("127.0.0.1","test","root","",3306); 17 | qDebug() << " connection name:" << tempDB2.connectionName() << "is vaild:" << tempDB2.isOpen() <<"\n"; 18 | QSqlDatabase tempDB3 = NDBPool::getNewConnection("127.0.0.1","test","root","",3306); 19 | qDebug() << " connection name:" << tempDB3.connectionName() << "is vaild:" << tempDB3.isOpen() <<"\n"; 20 | QSqlDatabase tempDB4 = NDBPool::getNewConnection("127.0.0.1","test","root","",3306); 21 | qDebug() << " connection name:" << tempDB4.connectionName() << "is vaild:" << tempDB4.isOpen() <<"\n"; 22 | 23 | // release new connection 24 | NDBPool::closeConnection(tempDB); 25 | NDBPool::closeConnection(tempDB1); 26 | NDBPool::closeConnection(tempDB2); 27 | NDBPool::closeConnection(tempDB3); 28 | NDBPool::closeConnection(tempDB4); 29 | } 30 | 31 | // thread get new connnection 32 | threadTest tempTest; 33 | tempTest.startTest(); 34 | qDebug() << "/**************************结束测试用例**************************/"; 35 | return a.exec(); 36 | } 37 | -------------------------------------------------------------------------------- /example/manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Description of application 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /example/testconnection.cpp: -------------------------------------------------------------------------------- 1 | #include "testconnection.h" 2 | 3 | TestConnection::TestConnection(int param_num, QThread *parent) : QThread(parent),threadNum(param_num) 4 | { 5 | } 6 | 7 | void TestConnection::run() 8 | { 9 | QSqlDatabase innerDB = NDBPool::getNewConnection("127.0.0.1","test","root","",3306); 10 | qDebug() << "short thread no:" << threadNum << "connection name:" << innerDB.connectionName() << "db is vaild:" << innerDB.isOpen() << "\n"; 11 | QThread::msleep(2000); 12 | NDBPool::closeConnection(innerDB); 13 | QSqlDatabase innerDB_002 = NDBPool::getNewConnection("127.0.0.1","test","root","",3306,true,"daodaoliang"); 14 | qDebug() << "long thread no:" << threadNum << "connection name:" << innerDB_002.connectionName() << "db is vaild:" << innerDB_002.isOpen() << "\n"; 15 | this->quit(); 16 | } 17 | 18 | -------------------------------------------------------------------------------- /example/testconnection.h: -------------------------------------------------------------------------------- 1 | #ifndef TESTCONNECTION_H 2 | #define TESTCONNECTION_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | class TestConnection : public QThread 10 | { 11 | Q_OBJECT 12 | public: 13 | explicit TestConnection(int param_num,QThread *parent = 0); 14 | void run(); 15 | int threadNum; 16 | }; 17 | 18 | #endif // TESTCONNECTION_H 19 | -------------------------------------------------------------------------------- /example/threadtest.cpp: -------------------------------------------------------------------------------- 1 | #include "threadtest.h" 2 | 3 | threadTest::threadTest(QObject *parent) : QObject(parent) 4 | { 5 | mPrivate= NULL; 6 | } 7 | 8 | threadTest::~threadTest() 9 | { 10 | if(mPrivate){ 11 | mPrivate->deleteLater(); 12 | } 13 | } 14 | 15 | void threadTest::startTest() 16 | { 17 | mPrivate = new QTimer; 18 | mPrivate->setInterval(1000); 19 | connect(mPrivate,SIGNAL(timeout()), this, SLOT(start_test_short_connect())); 20 | mPrivate->start(); 21 | } 22 | 23 | void threadTest::start_test_short_connect() 24 | { 25 | QStack connectlist; 26 | for(int tempIndex =0; tempIndex != 10; ++tempIndex){ 27 | TestConnection * temp = new TestConnection(tempIndex); 28 | connectlist.push(temp); 29 | temp->start(); 30 | connect(temp,SIGNAL(finished()),temp,SLOT(deleteLater())); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /example/threadtest.h: -------------------------------------------------------------------------------- 1 | #ifndef THREADTEST_H 2 | #define THREADTEST_H 3 | 4 | #include 5 | #include "testconnection.h" 6 | #include 7 | class threadTest : public QObject 8 | { 9 | Q_OBJECT 10 | public: 11 | explicit threadTest(QObject *parent = 0); 12 | ~threadTest(); 13 | void startTest(); 14 | public slots: 15 | void start_test_short_connect(); 16 | private: 17 | QTimer *mPrivate; 18 | }; 19 | 20 | #endif // THREADTEST_H 21 | -------------------------------------------------------------------------------- /scripts/clear.bat: -------------------------------------------------------------------------------- 1 | rmdir /S /Q %~dp0..\NDBPool\release 2 | rmdir /S /Q %~dp0..\NDBPool\debug 3 | rmdir /S /Q %~dp0..\NDBPool\build_ 4 | rmdir /S /Q %~dp0..\example\build_ 5 | rmdir /S /Q %~dp0..\example\release 6 | rmdir /S /Q %~dp0..\example\debug 7 | rmdir /S /Q %~dp0..\bin 8 | del /Q %~dp0..\Makefile* 9 | del /Q %~dp0..\NDBPool\Makefile* 10 | del /Q %~dp0..\example\Makefile* 11 | -------------------------------------------------------------------------------- /scripts/pro_arch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daodaoliang/NDBPool/cb4d836fcb07cf52d0700a38ee9467eec200c025/scripts/pro_arch.png -------------------------------------------------------------------------------- /scripts/系统架构.bmpr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/daodaoliang/NDBPool/cb4d836fcb07cf52d0700a38ee9467eec200c025/scripts/系统架构.bmpr --------------------------------------------------------------------------------