QT資料庫連線池的實現
mysql.h檔案
#ifndef MYSQL #define MYSQL #include <QtSql> #include <QQueue> #include <QString> #include <QMutex> #include <QMutexLocker> #include<QDebug> #include<QSettings>//配置檔案 class ConnectionPool { public: static void release(); // 關閉所有的資料庫連線 static QSqlDatabase openConnection(); // 獲取資料庫連線 static void closeConnection(QSqlDatabase connection); // 釋放資料庫連接回連線池 ~ConnectionPool(); private: static ConnectionPool& getInstance(); ConnectionPool(); ConnectionPool(const ConnectionPool &other); ConnectionPool& operator=(const ConnectionPool &other); QSqlDatabase createConnection(const QString &connectionName); // 建立資料庫連線 QQueue<QString> usedConnectionNames; // 已使用的資料庫連線名 QQueue<QString> unusedConnectionNames; // 未使用的資料庫連線名 // 資料庫資訊 QString hostName; QString databaseName; QString username; QString password; QString databaseType; bool testOnBorrow; // 取得連線的時候驗證連線是否有效 QString testOnBorrowSql; // 測試訪問資料庫的 SQL int maxWaitTime; // 獲取連線最大等待時間 int waitInterval; // 嘗試獲取連線時等待間隔時間 int maxConnectionCount; // 最大連線數 static QMutex mutex; static QWaitCondition waitConnection; static ConnectionPool *instance; }; #endif // MYSQL
.cpp檔案
#include "mysql.h" #include "login.h" //#include <QDebug> QMutex ConnectionPool::mutex; QWaitCondition ConnectionPool::waitConnection; ConnectionPool* ConnectionPool::instance = NULL; ConnectionPool::ConnectionPool() { hostName = "localhost";//主機名 databaseName = "quick";//需要訪問的資料庫 username = "root";//使用者名稱 password = "****";//密碼 databaseType = "QMYSQL";//資料庫型別 testOnBorrow = true; testOnBorrowSql = "SELECT 1"; maxWaitTime = 1000; waitInterval = 200; maxConnectionCount = 1000; } ConnectionPool::~ConnectionPool() { // 銷燬連線池的時候刪除所有的連線 foreach(QString connectionName, usedConnectionNames) { QSqlDatabase::removeDatabase(connectionName); } foreach(QString connectionName, unusedConnectionNames) { QSqlDatabase::removeDatabase(connectionName); } } ConnectionPool& ConnectionPool::getInstance() { if (NULL == instance) { QMutexLocker locker(&mutex); if (NULL == instance) { instance = new ConnectionPool(); } } return *instance; } void ConnectionPool::release() { QMutexLocker locker(&mutex); delete instance; instance = NULL; } QSqlDatabase ConnectionPool::openConnection() { ConnectionPool& pool = ConnectionPool::getInstance(); QString connectionName; QMutexLocker locker(&mutex); // 已建立連線數 int connectionCount = pool.unusedConnectionNames.size() + pool.usedConnectionNames.size(); // 如果連線已經用完,等待 waitInterval 毫秒看看是否有可用連線,最長等待 maxWaitTime 毫秒 for (int i = 0; i < pool.maxWaitTime && pool.unusedConnectionNames.size() == 0 && connectionCount == pool.maxConnectionCount; i += pool.waitInterval) { waitConnection.wait(&mutex, pool.waitInterval); // 重新計算已建立連線數 connectionCount = pool.unusedConnectionNames.size() + pool.usedConnectionNames.size(); } if (pool.unusedConnectionNames.size() > 0) { // 有已經回收的連線,複用它們 connectionName = pool.unusedConnectionNames.dequeue(); } else if (connectionCount < pool.maxConnectionCount) { // 沒有已經回收的連線,但是沒有達到最大連線數,則建立新的連線 connectionName = QString("Connection-%1").arg(connectionCount + 1); } else { // 已經達到最大連線數 qDebug() << "Cannot create more connections."; return QSqlDatabase(); } // 建立連線 QSqlDatabase db = pool.createConnection(connectionName); // 有效的連線才放入 usedConnectionNames if (db.isOpen()) { pool.usedConnectionNames.enqueue(connectionName); } return db; } void ConnectionPool::closeConnection(QSqlDatabase connection) { ConnectionPool& pool = ConnectionPool::getInstance(); QString connectionName = connection.connectionName(); // 如果是我們建立的連線,從 used 裡刪除,放入 unused 裡 if (pool.usedConnectionNames.contains(connectionName)) { QMutexLocker locker(&mutex); pool.usedConnectionNames.removeOne(connectionName); pool.unusedConnectionNames.enqueue(connectionName); waitConnection.wakeOne(); } } QSqlDatabase ConnectionPool::createConnection(const QString &connectionName) { // 連線已經建立過了,複用它,而不是重新建立 if (QSqlDatabase::contains(connectionName)) { QSqlDatabase db1 = QSqlDatabase::database(connectionName); if (testOnBorrow) { // 返回連線前訪問資料庫,如果連線斷開,重新建立連線 qDebug() << "Test connection on borrow, execute:" << testOnBorrowSql << ", for" << connectionName; QSqlQuery query(testOnBorrowSql, db1); if (query.lastError().type() != QSqlError::NoError && !db1.open()) { qDebug() << "Open datatabase error:" << db1.lastError().text(); return QSqlDatabase(); } } return db1; } // 建立一個新的連線 QSqlDatabase db = QSqlDatabase::addDatabase(databaseType, connectionName); db.setHostName(hostName); db.setDatabaseName(databaseName); db.setUserName(username); db.setPassword(password); //db.setPort(3306); if (!db.open()) { qDebug() << "Open datatabase error:" << db.lastError().text(); return QSqlDatabase(); } return db; }
相關推薦
QT資料庫連線池的實現
mysql.h檔案 #ifndef MYSQL #define MYSQL #include <QtSql> #include <QQueue> #include <QString> #include <QMutex> #i
servlet+jsp+mysql+資料庫連線池實現註冊登陸驗證碼功能
首先專案的結構及所用到的jar包如圖: 主要用到jdbc和jstl的jar包,大家可自行去相應網站下載 一、資料庫和資料表的建立 1.建庫語句: create database test; 2.建表語句: CREATE TABLE `t_users` (
自定義資料庫連線池實現方式 MySQL
應用程式直接獲取資料庫連線缺點 使用者每次請求都會建立一次資料庫連線,並且資料庫建立連線會消耗相對大的資源和時間。 如果針對於個別的工具或者是大量的程式碼測試甚至系統執行,對資料庫操作次數頻繁,極大的佔用資料庫資源,有可能會發生宕機或者記憶體溢位的現象。 而在大多的專案中,常常用到阿里巴
JDBC資料庫連線池實現原理(手動實現)
一、普通的資料庫連線 如下圖所示,個使用者獲取資料庫資料都要單獨建立一個jdbc連線,當用戶獲取資料完成後再將連線釋放,可見對cpu的資源消耗很大。 二
自定義資料庫連線池實現方式 MySQL
應用程式直接獲取資料庫連線缺點 使用者每次請求都會建立一次資料庫連線,並且資料庫建立連線會消耗相對大的資源和時間。 如果針對於個別的工具或者是大量的程式碼測試甚至系統執行,對資料庫操作次數頻繁,極大的佔用資料庫資源,有可能會發生宕機或者記憶體溢位的現象。 而在大多的專案中
java資料庫連線池實現原理
原文:http://blog.csdn.net/frightingforambition/article/details/25464129 一、為什麼在連線資料庫時要使用連線池 資料庫連線是一種關鍵的有限的昂貴的資源,這一點在多使用者的網頁應用程式中體現得
自定義實現資料庫連線池
資料庫連線池: >資料庫的連線物件建立工作,比較消耗效能 >一開始先在記憶體中開闢一塊空間(集合) , 先往池子裡面放置 多個連線物件。 後面需要連線的話,直接從池子裡面去。不要去自己建立連線了。 使用完畢, 要記得歸還連線。確保連線物件能迴圈利用。即建立
【Java】Spring和Tomcat自帶的連線池實現資料庫操作
@[toc] 前言 前面我們已經用Spring和傳統的Jdbc實現資料庫操作、Spring和JdbcTemplate實現資料庫操作。但是這些都是基於直連的資料來源進行的,現在我們將介紹基於連線池的資料來源進行資料庫操作。前面幾個步驟都相同。 建立資料庫 首先建立我們的資料庫(這裡我使用的是Mysql)
理解資料庫連線池底層原理之手寫實現
前言 資料庫連線池的基本思想是:為資料庫連線建立一個“緩衝池”,預先在池中放入一定數量的資料庫連線管道,需要時,從池子中取出管道進行使用,操作完畢後,在將管道放入池子中,從而避免了頻繁的向資料庫申請資源,釋放資源帶來的效能損耗。在如今的分散式系統當中,系統的QPS瓶頸往往就
Flask學習筆記之——藍圖、基於DBUtils實現資料庫連線池、上下文管理等
面向物件知識回顧 子類繼承父類的三種方式 class Dog(Animal): #子類 派生類 def __init__(self,name,breed, life_value,aggr): # Animal.__init__(self
Flask學習【第3篇】:藍圖、基於DBUtils實現資料庫連線池、上下文管理等 基於DBUtils實現資料庫連線池
基於DBUtils實現資料庫連線池 小知識: 1、子類繼承父類的三種方式 class Dog(Animal): #子類 派生類 def
Java 使用動態代理和觀察者模式+threadlocal實現資料庫連線池
當我們使用資料庫連線池時,如果多執行緒連線資料庫時,當超過5個執行緒連線資料庫時,那麼在第6個執行緒包括之後就連線不到資料庫了,該怎麼處理。 這裡用了java動態代理來這裡用了java的動態代理來代理資料庫的連線,攔截連線的close方法。並且給代理的連線加上一
python3.6實現mysql資料庫連線池
首先安裝資料連線池模組 pip3 install DBUtils 然後安裝mysql驅動包 pip3 install PyMySQL 安裝完成之後,在專案中settings檔案裡面配置好資料連線資訊,如下圖: 新建一個myql_help檔案,名稱自己取,然後複製參考以下
基於DBUtils實現資料庫連線池
小知識: 1、子類繼承父類的三種方式 class Dog(Animal): #子類 派生類 def __init__(self,name,breed, life_value,aggr): # Animal.__init__(self,nam
JDBC/InvocationHandler動態代理實現資料庫連線池、資料來源
Java的JDBC程式設計中,資料庫的連線和關閉是十分耗費資源的。當對資料庫的訪問不是很頻繁時,可以在每次訪問資料庫時建立一個連線,用完之後關閉。但是,對於一個複雜的資料庫應用,頻繁的建立、關閉連線,會極大的減低系統性能,造成瓶頸。所以可以使用資料庫連線池來達到
Qt資料庫之資料庫連線池
在前面的章節裡,我們使用了下面的函式建立和取得資料庫連線: void createConnectionByName(const QString &connectionName) { QSqlDatabase db = QSqlDatabase::addDatabase("QMYS
資料庫連線池 單例模式的實現
Java應用程式訪問資料庫的基本原理 在Java語言中,JDBC(Java DataBase Connection)是應用程式與資料庫溝通的橋樑, 即Java語言通過JDBC技術訪問資料庫。JDBC是一種“開放”的方案,它為資料庫應用開發人員﹑資料庫前臺工具開
資料庫連線池底層原理以及手寫實現
資料庫連線池的基本思想是:為資料庫連線建立一個“緩衝池”,預先在池中放入一定數量的資料庫連線管道,需要時,從池子中取出管道進行使用,操作完畢後,在將管道放入池子中,從而避免了頻繁的向資料庫申請資源,釋放資源帶來的效能損耗。 在如今的分散式系統當中,系統的QPS瓶頸往往就
java之實現自己的資料庫連線池
最近仿mybatis寫了一個自己的orm框架 專案已上傳到github上 https://github.com/skybluehhx/MYORM.git,既然是orm框架肯定需要事務管理器和資料庫連線池,下面將介紹我自己實現一個連線池 (主要藉助阻塞佇列) 首先定義一個介面
一個簡單資料庫連線池的實現
一、已實現功能 資料庫連線快取。將資料庫連線與執行緒ID繫結並提供執行資料庫操作時檢測。資料庫連線超時檢測。初始化資料庫環境,包括初始化資料庫,資料庫使用者,資料庫表。 二、程式碼列表: 1、MySqlDBManager: 用於管理資料庫配置、初始化資料庫環境及建立