基於MySQL Connector/C++的資料庫連線池
阿新 • • 發佈:2019-02-10
本文來自:http://www.oschina.net/code/snippet_583625_19818
/* *File: connection_pool.h *Author: csc */ #ifndef _CONNECTION_POOL_H #define _CONNECTION_POOL_H #include <mysql_connection.h> #include <mysql_driver.h> #include <cppconn/exception.h> #include <cppconn/driver.h> #include <cppconn/connection.h> #include <cppconn/resultset.h> #include <cppconn/prepared_statement.h> #include <cppconn/statement.h> #include <pthread.h> #include <list> using namespace std; using namespace sql; class ConnPool { private: int curSize; //當前已建立的資料庫連線數量 int maxSize; //連線池中定義的最大資料庫連線數 string username; string password; string url; list<Connection*> connList; //連線池的容器佇列 pthread_mutex_t lock; //執行緒鎖 static ConnPool *connPool; Driver*driver; Connection*CreateConnection(); //建立一個連線 void InitConnection(int iInitialSize); //初始化資料庫連線池 void DestoryConnection(Connection *conn); //銷燬資料庫連線物件 void DestoryConnPool(); //銷燬資料庫連線池 ConnPool(string url, string user, string password, int maxSize); //構造方法 public: ~ConnPool(); Connection*GetConnection(); //獲得資料庫連線 void ReleaseConnection(Connection *conn); //將資料庫連線放回到連線池的容器中 static ConnPool *GetInstance(); //獲取資料庫連線池物件 }; #endif /*_CONNECTION_POOL_H */
/* * connection_pool.cpp * * Created on: 2013-3-29 * Author: csc */ #include <stdexcept> #include <exception> #include <stdio.h> #include "connection_pool.h" using namespace std; using namespace sql; ConnPool *ConnPool::connPool = NULL; //連線池的建構函式 ConnPool::ConnPool(string url, string userName, string password, int maxSize) { this->maxSize = maxSize; this->curSize = 0; this->username = userName; this->password = password; this->url = url; try { this->driver = sql::mysql::get_driver_instance(); } catch (sql::SQLException&e) { perror("驅動連接出錯;\n"); } catch (std::runtime_error&e) { perror("執行出錯了\n"); } this->InitConnection(maxSize / 2); } //獲取連線池物件,單例模式 ConnPool*ConnPool::GetInstance() { if (connPool == NULL) { connPool = new ConnPool("tcp://127.0.0.1:3306", "root", "123456", 50); } return connPool; } //初始化連線池,建立最大連線數的一半連線數量 void ConnPool::InitConnection(int iInitialSize) { Connection*conn; pthread_mutex_lock(&lock); for (int i = 0; i < iInitialSize; i++) { conn = this->CreateConnection(); if (conn) { connList.push_back(conn); ++(this->curSize); } else { perror("建立CONNECTION出錯"); } } pthread_mutex_unlock(&lock); } //建立連線,返回一個Connection Connection* ConnPool::CreateConnection() { Connection*conn; try { conn = driver->connect(this->url, this->username, this->password); //建立連線 return conn; } catch (sql::SQLException&e) { perror("建立連接出錯"); return NULL; } catch (std::runtime_error&e) { perror("執行時出錯"); return NULL; } } //在連線池中獲得一個連線 Connection*ConnPool::GetConnection() { Connection*con; pthread_mutex_lock(&lock); if (connList.size() > 0) { //連線池容器中還有連線 con = connList.front(); //得到第一個連線 connList.pop_front(); //移除第一個連線 if (con->isClosed()) { //如果連線已經被關閉,刪除後重新建立一個 delete con; con = this->CreateConnection(); } //如果連線為空,則建立連接出錯 if (con == NULL) { --curSize; } pthread_mutex_unlock(&lock); return con; } else { if (curSize < maxSize) { //還可以建立新的連線 con = this->CreateConnection(); if (con) { ++curSize; pthread_mutex_unlock(&lock); return con; } else { pthread_mutex_unlock(&lock); return NULL; } } else { //建立的連線數已經達到maxSize pthread_mutex_unlock(&lock); return NULL; } } } //回收資料庫連線 void ConnPool::ReleaseConnection(sql::Connection * conn) { if (conn) { pthread_mutex_lock(&lock); connList.push_back(conn); pthread_mutex_unlock(&lock); } } //連線池的解構函式 ConnPool::~ConnPool() { this->DestoryConnPool(); } //銷燬連線池,首先要先銷燬連線池的中連線 void ConnPool::DestoryConnPool() { list<Connection*>::iterator icon; pthread_mutex_lock(&lock); for (icon = connList.begin(); icon != connList.end(); ++icon) { this->DestoryConnection(*icon); //銷燬連線池中的連線 } curSize = 0; connList.clear(); //清空連線池中的連線 pthread_mutex_unlock(&lock); } //銷燬一個連線 void ConnPool::DestoryConnection(Connection* conn) { if (conn) { try { conn->close(); } catch (sql::SQLException&e) { perror(e.what()); } catch (std::exception&e) { perror(e.what()); } delete conn; } }
/* * main.cpp * * Created on: 2013-3-26 * Author: holy */ #include "connection_pool.h" namespace ConnectMySQL { //初始化連線池 ConnPool *connpool = ConnPool::GetInstance(); void run() { Connection *con; Statement *state; ResultSet *result; // 從連線池中獲取mysql連線 con = connpool->GetConnection(); state = con->createStatement(); state->execute("use holy"); // 查詢 result = state->executeQuery("select * from student where id < 1002"); // 輸出查詢 while (result->next()) { int id = result->getInt("id"); string name = result->getString("name"); cout << id << " : " << name << endl; } delete state; connpool->ReleaseConnection(con); } } int main(int argc, char* argv[]) { ConnectMySQL::run(); return 0; }