真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

基于MysqlConnector/C++的數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)是怎樣的

基于MySQLConnector/C++的數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)是怎樣的,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

成都創(chuàng)新互聯(lián)公司是一家成都網(wǎng)站建設(shè)、網(wǎng)站制作,提供網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),網(wǎng)站制作,建網(wǎng)站,按需定制網(wǎng)站,網(wǎng)站開(kāi)發(fā)公司,于2013年創(chuàng)立是互聯(lián)行業(yè)建設(shè)者,服務(wù)者。以提升客戶(hù)品牌價(jià)值為核心業(yè)務(wù),全程參與項(xiàng)目的網(wǎng)站策劃設(shè)計(jì)制作,前端開(kāi)發(fā),后臺(tái)程序制作以及后期項(xiàng)目運(yùn)營(yíng)并提出專(zhuān)業(yè)建議和思路。

1.連接池的介紹:

1.1應(yīng)用背景:

一般的應(yīng)用程序都會(huì)訪(fǎng)問(wèn)到數(shù)據(jù)庫(kù),在程序訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)的時(shí)候,每一次數(shù)據(jù)訪(fǎng)問(wèn)請(qǐng)求都必須經(jīng)過(guò)下面幾個(gè)步驟:建立數(shù)據(jù)庫(kù)連接,打開(kāi)數(shù)據(jù)庫(kù),對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行操作,關(guān)閉數(shù)據(jù)庫(kù)連接。而建立數(shù)據(jù)庫(kù)連接和打開(kāi)數(shù)據(jù)庫(kù)是一件很消耗資源并且費(fèi)時(shí)的工作,如果在系統(tǒng)中很頻繁的發(fā)生這種數(shù)據(jù)庫(kù)連接,必然會(huì)影響到系統(tǒng)的性能,甚至?xí)?dǎo)致系統(tǒng)的崩潰。

1.2技術(shù)思想:

在系統(tǒng)初始化階段,建立一定數(shù)量的數(shù)據(jù)庫(kù)連接對(duì)象(Connection),并將其存儲(chǔ)在連接池中定義的容器中。當(dāng)有數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)請(qǐng)求時(shí),就從連接池中的這個(gè)容器中拿出一個(gè)連接;當(dāng)容器中的連接已經(jīng)用完,并且還沒(méi)有達(dá)到系統(tǒng)定義的最大連接數(shù)時(shí),可以再創(chuàng)建一個(gè)新的連接,當(dāng)當(dāng)前使用的連接數(shù)達(dá)到最大連接數(shù)時(shí),就要等待其他訪(fǎng)問(wèn)請(qǐng)求將連接放回容器后才能使用。當(dāng)使用完連接的時(shí)候,必須將連接放回容器中,這樣不同的數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)請(qǐng)求就可以共享這些連接,通過(guò)重復(fù)使用這些已經(jīng)建立的數(shù)據(jù)庫(kù)連接,可以解決上節(jié)中說(shuō)到的頻繁建立連接的缺點(diǎn),從而提高了系統(tǒng)的性能。

經(jīng)過(guò)上述描述,我們可以歸納出數(shù)據(jù)庫(kù)連接池的主要操作:

(1)首先建立一個(gè)數(shù)據(jù)庫(kù)連接池對(duì)象

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

(3)當(dāng)有數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)請(qǐng)求時(shí),直接從連接池的容器中得到一個(gè)連接,這里出現(xiàn)三種情況:

(a)當(dāng)容器中的還有連接時(shí),則返回給數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)請(qǐng)求者一個(gè)連接

(b)當(dāng)容器中沒(méi)有連接時(shí),并且當(dāng)前建立的連接數(shù)沒(méi)有達(dá)到系統(tǒng)定義的最大連接數(shù),則創(chuàng)建一個(gè)新的數(shù)據(jù)庫(kù)連接。

(c)當(dāng)容器中的沒(méi)有連接并且當(dāng)前建立的連接數(shù)達(dá)到系統(tǒng)定義的最大連接數(shù),則當(dāng)前訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)請(qǐng)求就要等待其他訪(fǎng)問(wèn)請(qǐng)求釋放連接。

(4)當(dāng)數(shù)據(jù)庫(kù)訪(fǎng)問(wèn)完成后,應(yīng)該將連接放回連接池的容器中。

(5)當(dāng)服務(wù)停止時(shí),需要先釋放數(shù)據(jù)庫(kù)連接池中的所有數(shù)據(jù)庫(kù)連接,然后再釋放數(shù)據(jù)庫(kù)連接池對(duì)象。

2.編程實(shí)現(xiàn):

頭文件(connection_pool.h):

[html] view
plaincopy

  1.  /*  

  2.          *File: connection_pool.h  

  3.           *Author: csc  

  4.      */  

  5. #ifndef_CONNECTION_POOL_H  

  6. #define _CONNECTION_POOL_H  

  7. #include

  8. #include

  9. #include

  10. #include

  11. #include

  12. #include

  13. #include

  14. #include

  15. #include

  16. #include

  17. usingnamespace std;  

  18. usingnamespace sql;  

  19. classConnPool{  

  20. private:  

  21. intcurSize;//當(dāng)前已建立的數(shù)據(jù)庫(kù)連接數(shù)量  

  22. intmaxSize;//連接池中定義的最大數(shù)據(jù)庫(kù)連接數(shù)  

  23. stringusername;  

  24. stringpassword;  

  25. stringurl;  

  26. listconnList;//連接池的容器隊(duì)列  

  27. pthread_mutex_tlock;//線(xiàn)程鎖  

  28. staticConnPool *connPool;  

  29. Driver*driver;  

  30. Connection*CreateConnection();//創(chuàng)建一個(gè)連接  

  31. voidInitConnection(int iInitialSize);//初始化數(shù)據(jù)庫(kù)連接池  

  32. voidDestoryConnection(Connection *conn);//銷(xiāo)毀數(shù)據(jù)庫(kù)連接對(duì)象  

  33. voidDestoryConnPool();//銷(xiāo)毀數(shù)據(jù)庫(kù)連接池  

  34. ConnPool(stringurl,string user,string password,int maxSize);//構(gòu)造方法  

  35. public:  

  36. ~ConnPool();  

  37. Connection*GetConnection();//獲得數(shù)據(jù)庫(kù)連接  

  38. voidReleaseConnection(Connection *conn);//將數(shù)據(jù)庫(kù)連接放回到連接池的容器中  

  39. staticConnPool *GetInstance();//獲取數(shù)據(jù)庫(kù)連接池對(duì)象  

  40. };  

  41. #endif  /*_CONNECTION_POOL_H */  

頭文件中定義了一個(gè)容器connList,里面存放了很多個(gè)未使用的連接;在對(duì)容器內(nèi)的連接進(jìn)行操作的時(shí)候,需要加鎖來(lái)保證程序的安全性,所以頭文件中定義了一個(gè)lock,通過(guò)使用lock保證了同一時(shí)間只有一個(gè)線(xiàn)程對(duì)容器進(jìn)行操作。

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

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

連接使用完以后,需要將連接放回連接池中,通過(guò)ReleaseConnection(sql::Connection* conn)方法實(shí)現(xiàn),它的實(shí)現(xiàn)非常簡(jiǎn)單,就是將傳進(jìn)來(lái)的connection連接添加到連接池的容器中。

當(dāng)需要回收連接池的內(nèi)存空間時(shí),需要先回收連接池中所有連接的內(nèi)存空間,然后再釋放連接池對(duì)象的內(nèi)存空間。

實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接池主要的步驟就是上述這些,具體的代碼實(shí)現(xiàn)如下所示:

[cpp] view
plaincopy

  1. #include

  2. #include

  3. #include

  4. #include"connection_pool.h"

  5. usingnamespace std;  

  6. usingnamespace sql;  

  7. ConnPool*ConnPool::connPool=NULL;  

  8. //連接池的構(gòu)造函數(shù)

  9. ConnPool::ConnPool(stringurl, string userName,string password, int maxSize)  

  10. {  

  11.     this->maxSize=maxSize;  

  12.     this->curSize=0;  

  13.     this->username=userName;  

  14.     this->password=password;  

  15.     this->url=url;  

  16.     try{  

  17.         this->driver=sql::mysql::get_driver_instance();  

  18.     }  

  19.     catch(sql::SQLException&e)  

  20.     {  

  21.         perror("驅(qū)動(dòng)連接出錯(cuò);\n");  

  22.     }  

  23.     catch(std::runtime_error&e)  

  24.     {  

  25.         perror("運(yùn)行出錯(cuò)了\n");  

  26.     }  

  27.     this->InitConnection(maxSize/2);  

  28. }  

  29. //獲取連接池對(duì)象,單例模式

  30. ConnPool*ConnPool::GetInstance(){  

  31.     if(connPool==NULL)  

  32.     {  

  33.         connPool=newConnPool("tcp://127.0.0.1:3306","root","root",50);  

  34.     }  

  35.     returnconnPool;  

  36. }  

  37. //初始化連接池,創(chuàng)建最大連接數(shù)的一半連接數(shù)量

  38. voidConnPool::InitConnection(int iInitialSize)  

  39. {  

  40.     Connection*conn;  

  41.     pthread_mutex_lock(&lock);  

  42.     for(inti=0;i

  43.     {  

  44.         conn=this->CreateConnection();  

  45.         if(conn){  

  46.             connList.push_back(conn);  

  47.             ++(this->curSize);  

  48.         }  

  49.         else

  50.         {  

  51.             perror("創(chuàng)建CONNECTION出錯(cuò)");  

  52.         }  

  53.     }  

  54.     pthread_mutex_unlock(&lock);  

  55. }  

  56. //創(chuàng)建連接,返回一個(gè)Connection

  57. Connection*ConnPool::CreateConnection(){  

  58.     Connection*conn;  

  59.     try{  

  60.         conn=driver->connect(this->url,this->username,this->password);//建立連接

  61.         returnconn;  

  62.     }  

  63.     catch(sql::SQLException&e)  

  64.     {  

  65.         perror("創(chuàng)建連接出錯(cuò)");  

  66.         returnNULL;  

  67.     }  

  68.     catch(std::runtime_error&e)  

  69.     {  

  70.         perror("運(yùn)行時(shí)出錯(cuò)");  

  71.         returnNULL;  

  72.     }  

  73. }  

  74. //在連接池中獲得一個(gè)連接

  75. Connection*ConnPool::GetConnection(){  

  76.     Connection*con;  

  77.     pthread_mutex_lock(&lock);  

  78.     if(connList.size()>0)//連接池容器中還有連接

  79.     {  

  80.         con=connList.front();//得到第一個(gè)連接

  81.         connList.pop_front();//移除第一個(gè)連接

  82.         if(con->isClosed())//如果連接已經(jīng)被關(guān)閉,刪除后重新建立一個(gè)

  83.         {  

  84.             deletecon;  

  85.             con=this->CreateConnection();  

  86.         }  

  87.         //如果連接為空,則創(chuàng)建連接出錯(cuò)

  88.         if(con==NULL)  

  89.         {  

  90.             --curSize;  

  91.         }  

  92.         pthread_mutex_unlock(&lock);  

  93.         returncon;  

  94.     }  

  95.     else{  

  96.         if(curSize< maxSize){//還可以創(chuàng)建新的連接

  97.             con= this->CreateConnection();  

  98.             if(con){  

  99.                 ++curSize;  

  100.                 pthread_mutex_unlock(&lock);  

  101.                 returncon;  

  102.             }  

  103.             else{  

  104.                 pthread_mutex_unlock(&lock);  

  105.                 returnNULL;  

  106.             }  

  107.         }  

  108.         else{//建立的連接數(shù)已經(jīng)達(dá)到maxSize

  109.             pthread_mutex_unlock(&lock);  

  110.             returnNULL;  

  111.         }  

  112.     }  

  113. }  

  114. //回收數(shù)據(jù)庫(kù)連接

  115. voidConnPool::ReleaseConnection(sql::Connection * conn){  

  116.     if(conn){  

  117.         pthread_mutex_lock(&lock);  

  118.         connList.push_back(conn);  

  119.         pthread_mutex_unlock(&lock);  

  120.     }  

  121. }  

  122. //連接池的析構(gòu)函數(shù)

  123. ConnPool::~ConnPool()  

  124. {  

  125.     this->DestoryConnPool();  

  126. }  

  127. //銷(xiāo)毀連接池,首先要先銷(xiāo)毀連接池的中連接

  128. voidConnPool::DestoryConnPool(){  

  129.     list::iterator icon;  

  130.     pthread_mutex_lock(&lock);  

  131.     for(icon=connList.begin();icon!=connList.end();++icon)  

  132.     {  

  133.         this->DestoryConnection(*icon);//銷(xiāo)毀連接池中的連接

  134.     }  

  135.     curSize=0;  

  136.     connList.clear();//清空連接池中的連接

  137.     pthread_mutex_unlock(&lock);  

  138. }  

  139. //銷(xiāo)毀一個(gè)連接

  140. voidConnPool::DestoryConnection(Connection* conn)  

  141. {  

  142.     if(conn)  

  143.     {  

  144.         try{  

  145.             conn->close();  

  146.         }  

  147.         catch(sql::SQLException&e)  

  148.         {  

  149.             perror(e.what());  

  150.         }  

  151.         catch(std::exception&e)  

  152.         {  

  153.             perror(e.what());  

  154.         }  

  155.         deleteconn;  

  156.     }  

  157. }  

[cpp]
view plaincopyprint?

  1. /*

  2.  * main.cpp

  3.  *

  4.  *  Created on: 2013-3-26

  5.  *      Author: holy

  6.  */

  7. #include "connection_pool.h"

  8. namespace ConnectMySQL {  

  9. //初始化連接池

  10. ConnPool *connpool = ConnPool::GetInstance();  

  11. void run() {  

  12.     Connection *con;  

  13.     Statement *state;  

  14.     ResultSet *result;  

  15.     // 從連接池中獲取mysql連接

  16.     con = connpool->GetConnection();  

  17.     state = con->createStatement();  

  18.     state->execute("use holy");  

  19.     // 查詢(xún)

  20.     result = state->executeQuery("select * from student where id < 1002");  

  21.     // 輸出查詢(xún)

  22.     while (result->next()) {  

  23.         int id = result->getInt("id");  

  24.         string name = result->getString("name");  

  25.         cout << id << " : " << name << endl;  

  26.     }  

  27.     delete state;  

  28.     connpool->ReleaseConnection(con);  

  29. }  

  30. }  

  31. int main(int argc, char* argv[]) {  

  32.     ConnectMySQL::run();  

  33.     return 0;  

  34. }  

關(guān)于基于MysqlConnector/C++的數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)是怎樣的問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。


網(wǎng)站題目:基于MysqlConnector/C++的數(shù)據(jù)庫(kù)連接池的實(shí)現(xiàn)是怎樣的
文章網(wǎng)址:http://weahome.cn/article/pchdee.html

其他資訊

在線(xiàn)咨詢(xún)

微信咨詢(xún)

電話(huà)咨詢(xún)

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部