日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

基于MysqlConnector/C++的数据库连接池的实现

發布時間:2023/12/9 数据库 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于MysqlConnector/C++的数据库连接池的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

From: http://blog.csdn.net/educast/article/details/14164097

?

1.連接池的介紹:

1.1應用背景:

一般的應用程序都會訪問到數據庫,在程序訪問數據庫的時候,每一次數據訪問請求都必須經過下面幾個步驟:建立數據庫連接,打開數據庫,對數據庫中的數據進行操作,關閉數據庫連接。而建立數據庫連接和打開數據庫是一件很消耗資源并且費時的工作,如果在系統中很頻繁的發生這種數據庫連接,必然會影響到系統的性能,甚至會導致系統的崩潰。

1.2技術思想:

系統初始化階段,建立一定數量的數據庫連接對象(Connection),并將其存儲在連接池中定義的容器中。當有數據庫訪問請求時,就從連接池中的這個容器中拿出一個連接;當容器中的連接已經用完,并且還沒有達到系統定義的最大連接數時,可以再創建一個新的連接當當前使用的連接數達到最大連接數時,就要等待其他訪問請求將連接放回容器后才能使用。當使用完連接的時候,必須將連接放回容器中,這樣不同的數據庫訪問請求就可以共享這些連接,通過重復使用這些已經建立的數據庫連接,可以解決上節中說到的頻繁建立連接的缺點,從而提高了系統的性能。

經過上述描述,我們可以歸納出數據庫連接池的主要操作:

(1)首先建立一個數據庫連接池對象

(2)初始化一定數量的數據庫連接,放入連接池對象的容器中

(3)當有數據庫訪問請求時,直接從連接池的容器中得到一個連接,這里出現三種情況:

(a)當容器中的還有連接時,則返回給數據庫訪問請求者一個連接

(b)當容器中沒有連接時,并且當前建立的連接數沒有達到系統定義的最大連接數,則創建一個新的數據庫連接。

(c)當容器中的沒有連接并且當前建立的連接數達到系統定義的最大連接數,則當前訪問數據庫請求就要等待其他訪問請求釋放連接。

(4)當數據庫訪問完成后,應該將連接放回連接池的容器中。

(5)當服務停止時,需要先釋放數據庫連接池中的所有數據庫連接,然后釋放數據庫連接對象。

2.編程實現:

頭文件(connection_pool.h)

[html]?view plaincopy
  • ?/*??
  • ?????????*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>??
  • usingnamespace?std;??
  • usingnamespace?sql;??
  • ??
  • classConnPool{??
  • private:??
  • intcurSize;//當前已建立的數據庫連接數量??
  • intmaxSize;//連接池中定義的最大數據庫連接數??
  • stringusername;??
  • stringpassword;??
  • stringurl;??
  • list<Connection*>connList;//連接池的容器隊列??
  • pthread_mutex_tlock;//線程鎖??
  • staticConnPool?*connPool;??
  • Driver*driver;??
  • ??
  • Connection*CreateConnection();//創建一個連接??
  • voidInitConnection(int?iInitialSize);//初始化數據庫連接池??
  • voidDestoryConnection(Connection?*conn);//銷毀數據庫連接對象??
  • voidDestoryConnPool();//銷毀數據庫連接池??
  • ConnPool(stringurl,string?user,string?password,int?maxSize);//構造方法??
  • public:??
  • ~ConnPool();??
  • Connection*GetConnection();//獲得數據庫連接??
  • voidReleaseConnection(Connection?*conn);//將數據庫連接放回到連接池的容器中??
  • staticConnPool?*GetInstance();//獲取數據庫連接池對象??
  • };??
  • #endif??/*_CONNECTION_POOL_H?*/??


  • 頭文件中定義了一個容器connList,里面存放了很多個未使用的連接在對容器內的連接進行操作的時候,需要加鎖保證程序的安全性,所以頭文件中定義了一個lock,通過使用lock保證了同一時間只有一個線程對容器進行操作。

    連接池類要統一管理整個應用程序中的連接,所以在整個系統中只需要維護一個連接池對象,試想:如果系統中定義了多個連接池對象,那么每一個對象都可以建立maxSize個連接,這樣就失去了創建連接池的初衷,破環了通過連接池統一管理系統中連接的思想。所以這里使用單例模式編寫連接池類,單例模式確保一個類只有一個實例,自己進行實例化并且向整個系統提供這個實例。在頭文件中,我們定義了一個靜態的連接池對象connPool連接池類提供一個靜態的公共方法GetInstance(),外部程序通過調用這個方法來獲得連接池對象。并且將連接池類的構造函數定義為私有的,外部的應用程序不能夠通過new來實例化連接池類,只能通過GetInstance()方法獲得連接池對象;在GetInstance()方法中需要判斷連接池類中定義的connPool是否為NULL,若為NULL則調用私有構造函數實例化connPool,若不為空,則直接返回connPool。這樣就實現了連接池類的單例模式,從而保證了系統運行過程中只建立一個連接池類的實例對象。

    在實例化連接池類的對象時,要對連接池做一些初始化的操作,即建立一定數量的數據庫連接。程序中通過InitConnection(intiInitialSize)方法對連接池進行初始化,創建iInitialSize個連接,并且將這些連接放在連接池中的容器connList中,每新建一個連接,curSize就加1。當有數據庫訪問請求時,需要從連接池中獲取一個連接,通過GetConnection()方法實現:首先判斷容器中是否還有連接,如果有,則拿出容器中的第一個連接,并且將該連接移出容器;獲得的連接要進行判斷,如果連接已經關閉,則回收該連接的內存空間,并且重新創建一個連接;然后判斷新創建的連接是否為空,如果為空,則說明當前已經建立連接的數量并不是curSize個,而是(curSize-1)(應該除去這個空連接)。如果容器中已經沒有連接了,則要判斷當前的curSize值是否已經達到規定的maxSize,如果沒有小于maxSize,將建立一個新的連接(++curSize)。如果超過maxSize則等待其他數據庫訪問請求釋放數據庫連接。

    連接使用完以后,需要將連接放回連接池中,通過ReleaseConnection(sql::Connection* conn)方法實現,它的實現非常簡單,就是將傳進來的connection連接添加到連接池的容器中。

    當需要回收連接池的內存空間時,需要先回收連接池中所有連接的內存空間,然后再釋放連接池對象的內存空間。

    實現數據庫連接池主要的步驟就是上述這些,具體的代碼實現如下所示:

    [cpp]?view plaincopy
  • #include<stdexcept>??
  • #include<exception>??
  • #include<stdio.h>??
  • #include"connection_pool.h"??
  • ??
  • usingnamespace?std;??
  • usingnamespace?sql;??
  • ??
  • ConnPool*ConnPool::connPool=NULL;??
  • //連接池的構造函數??
  • ConnPool::ConnPool(stringurl,?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=newConnPool("tcp://127.0.0.1:3306","root","root",50);??
  • ????}??
  • ????returnconnPool;??
  • }??
  • //初始化連接池,創建最大連接數的一半連接數量??
  • voidConnPool::InitConnection(int?iInitialSize)??
  • {??
  • ????Connection*conn;??
  • ????pthread_mutex_lock(&lock);??
  • ????for(inti=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);//建立連接??
  • ????????returnconn;??
  • ????}??
  • ????catch(sql::SQLException&e)??
  • ????{??
  • ????????perror("創建連接出錯");??
  • ????????returnNULL;??
  • ????}??
  • ????catch(std::runtime_error&e)??
  • ????{??
  • ????????perror("運行時出錯");??
  • ????????returnNULL;??
  • ????}??
  • }??
  • //在連接池中獲得一個連接??
  • Connection*ConnPool::GetConnection(){??
  • ????Connection*con;??
  • ????pthread_mutex_lock(&lock);??
  • ????if(connList.size()>0)//連接池容器中還有連接??
  • ????{??
  • ????????con=connList.front();//得到第一個連接??
  • ????????connList.pop_front();//移除第一個連接??
  • ????????if(con->isClosed())//如果連接已經被關閉,刪除后重新建立一個??
  • ????????{??
  • ????????????deletecon;??
  • ????????????con=this->CreateConnection();??
  • ????????}??
  • ????????//如果連接為空,則創建連接出錯??
  • ????????if(con==NULL)??
  • ????????{??
  • ????????????--curSize;??
  • ????????}??
  • ????????pthread_mutex_unlock(&lock);??
  • ????????returncon;??
  • ????}??
  • ????else{??
  • ????????if(curSize<?maxSize){//還可以創建新的連接??
  • ????????????con=?this->CreateConnection();??
  • ????????????if(con){??
  • ????????????????++curSize;??
  • ????????????????pthread_mutex_unlock(&lock);??
  • ????????????????returncon;??
  • ????????????}??
  • ????????????else{??
  • ????????????????pthread_mutex_unlock(&lock);??
  • ????????????????returnNULL;??
  • ????????????}??
  • ????????}??
  • ????????else{//建立的連接數已經達到maxSize??
  • ????????????pthread_mutex_unlock(&lock);??
  • ????????????returnNULL;??
  • ????????}??
  • ????}??
  • }??
  • //回收數據庫連接??
  • voidConnPool::ReleaseConnection(sql::Connection?*?conn){??
  • ????if(conn){??
  • ????????pthread_mutex_lock(&lock);??
  • ????????connList.push_back(conn);??
  • ????????pthread_mutex_unlock(&lock);??
  • ????}??
  • }??
  • //連接池的析構函數??
  • ConnPool::~ConnPool()??
  • {??
  • ????this->DestoryConnPool();??
  • }??
  • //銷毀連接池,首先要先銷毀連接池的中連接??
  • voidConnPool::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);??
  • }??
  • //銷毀一個連接??
  • voidConnPool::DestoryConnection(Connection*?conn)??
  • {??
  • ????if(conn)??
  • ????{??
  • ????????try{??
  • ????????????conn->close();??
  • ????????}??
  • ????????catch(sql::SQLException&e)??
  • ????????{??
  • ????????????perror(e.what());??
  • ????????}??
  • ????????catch(std::exception&e)??
  • ????????{??
  • ????????????perror(e.what());??
  • ????????}??
  • ????????deleteconn;??
  • ????}??
  • } ?

  • [cpp] view plaincopyprint?
  • /*?
  • ?*?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;??
  • }??
  • 創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的基于MysqlConnector/C++的数据库连接池的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 色呦呦精品 | 一区二区乱子伦在线播放 | 久久a级片 | av有声小说一区二区三区 | www.操 | jizz国产视频 | 欧美日韩一本 | 国内精品99| 色久月| 乱淫67194 | 国产伦精品一区二区三区在线 | 蜜桃精品视频 | 欧美亚洲一区 | 亚洲精选在线观看 | 日韩一区二区三区视频 | 九九久视频 | 日本国产在线观看 | 日韩av高清在线观看 | 美女扒开腿免费视频 | 欧美黄视频在线观看 | 在线播放黄色av | 天天舔天天操 | 伊人网大香| 日韩性高潮 | 国产激情久久久久 | 国产精品精品国产色婷婷 | 丰满少妇一区二区三区 | 亚洲免费大全 | 日韩国产精品一区二区 | 五月天婷婷在线视频 | 国产视频一区在线播放 | 亚洲精品中文字幕成人片 | 99精品欧美一区二区三区综合在线 | 一区二区三区精品在线观看 | 日本三级小视频 | 少妇人妻好深好紧精品无码 | 西方裸体在线观看 | 欧美性生活网站 | 日本黄色高清视频 | 国产黄色网页 | 天天干,天天爽 | 亚洲春色在线观看 | 天天艹天天操 | 男生女生搞鸡视频 | 色综合久久久无码中文字幕波多 | 亚洲精品成人片在线观看精品字幕 | 欧美亚洲一区二区三区四区 | 国产中文自拍 | 4388成人网 | 亚洲在线免费视频 | 久久免费视频观看 | 日本黄色不卡视频 | 中文字幕精品一二三四五六七八 | 天天操天天干天天操 | 久久久久久久久免费看无码 | 国产精品精品软件视频 | 第九色 | 国产成人综合精品 | 小早川怜子一区二区三区 | 黄色大片免费观看视频 | 久久久久区 | 成人黄色短片 | 日韩av网站在线播放 | 国产在线看 | 欧美亚洲综合在线 | 日本一区二区免费视频 | jizz日本大全| 欧美1区2区3区 | 国产一二三区精品 | 久久毛片基地 | 午夜精品福利一区二区三区蜜桃 | 鲁鲁狠狠狠7777一区二区 | 九色论坛| 成人在线免费播放视频 | 国产一区二区三区影院 | 一级特黄毛片 | 东京热加勒比无码少妇 | www.国产视频 | 国产一级免费观看 | 亚洲黄片一区二区 | 亚洲天堂一区 | 亚州| 久久精品www人人爽人人 | 欧美三级黄色大片 | 中文字幕中文字幕 | 黄色片亚洲| 欧美天天性 | 精品久久久无码中文字幕 | 在线播放波多野结衣 | 国产福利一区二区三区 | 亚洲国产清纯 | 日韩av第一页| 国产久操视频 | 91黄色看片 | 中文字幕23 | 午夜欧美日韩 | 日本欧美一区二区三区 | 99视频免费观看 | 99久久久无码国产精品免费蜜柚 |