mysql c api簡單連線池
阿新 • • 發佈:2019-01-08
連線池為了解決頻繁的建立、銷燬所帶來的系統開銷。
簡而言之,就是 自己先建立一定量的連線,然後在需要的時候取出一條連線使用。
當然如果你只有一個執行緒連線資料庫,而且不是實時返回結果,那麼你完全不必用連線池。
想一下網路大型遊戲伺服器,你就明白為什麼需要連線池了。
自己敲程式碼寫了一個簡單的類,實現連線池,雖然沒有mysql++那麼強大,但是還是自己有收穫。
Csqlpool.h 標頭檔案實現如下:
Csqlpool.cpp 實現如下:#pragma once #include <WinSock2.h> #include <mysql.h> #include <list> #pragma comment( lib , "libmysql.lib" ) using namespace std; class Csqlpool { public: ~Csqlpool(void); static Csqlpool *GetSqlPool(); bool IniSqlPool( const char *host , const char *name , const char *pwd , unsigned int port , unsigned int conMax ); //初始化連線池 bool SelectDB( MYSQL *sql, const char *DB); //選擇資料庫 MYSQL *GetConnect(); // 獲取連線 void RelConnect(MYSQL *sql) ; // 釋放連線 MYSQL_RES* GetQuery( MYSQL *sql , const char *query); //mysql操作 增刪查改 void RelQuery(MYSQL_RES *res); //釋放MYSQL_RES資源 bool Query(MYSQL *sql , const char *query); //增、刪、改操作 protected: Csqlpool(void); private: list<MYSQL *> m_sql_free; //空閒連線 static Csqlpool *pSqlPool; CRITICAL_SECTION m_session; //獲取空閒執行緒 };
#include "StdAfx.h" #include "Csqlpool.h" Csqlpool *Csqlpool::pSqlPool = NULL; Csqlpool::Csqlpool(void) { InitializeCriticalSection( &m_session ); } Csqlpool::~Csqlpool(void) { while ( m_sql_free.size() ) { mysql_close( m_sql_free.front() ); m_sql_free.pop_front(); } DeleteCriticalSection(&m_session); } Csqlpool* Csqlpool::GetSqlPool() { if ( pSqlPool == NULL ) { return new Csqlpool; } return pSqlPool; } bool Csqlpool::IniSqlPool( const char *host ,const char *name , const char *pwd , unsigned int port , unsigned int conMax ) //初始化連線池 { int nsum = 0 ; for (unsigned int i = 0 ; i < conMax ;++i ) { MYSQL *pmysql; pmysql = mysql_init( (MYSQL*)NULL ); if ( pmysql != NULL ) { if ( mysql_real_connect( pmysql , host , name , pwd , NULL , 3306 , NULL , 0 ) ) { m_sql_free.push_back(pmysql); } else { if ( nsum++ == 100 ) { return false; } continue; } } continue; } return true; } bool Csqlpool::SelectDB( MYSQL *sql, const char *DB) //選擇資料庫 { if(mysql_select_db(sql , DB)) { return false; } return true; } MYSQL* Csqlpool::GetConnect() // 獲取連線 { if ( m_sql_free.size() ) { EnterCriticalSection(&m_session); MYSQL *mysql = m_sql_free.front(); m_sql_free.pop_front(); LeaveCriticalSection(&m_session); return mysql; } else return NULL; } void Csqlpool::RelConnect(MYSQL *sql) // 釋放連線 { EnterCriticalSection(&m_session); m_sql_free.push_back(sql); LeaveCriticalSection(&m_session); } MYSQL_RES* Csqlpool::GetQuery( MYSQL *sql , const char *query) //查詢操作 { if ( mysql_query( sql , query ) == 0 ) { return mysql_store_result( sql ); } else return NULL; } void Csqlpool::RelQuery(MYSQL_RES *res) //mysql_res release { mysql_free_result(res); } bool Csqlpool::Query(MYSQL *sql , const char *query) //增、刪、改操作 { if ( mysql_query( sql , query ) ) { return false; } return true; }
testsqlpool.cpp 測試檔案實現如下:
// testsqlpool.cpp : 定義控制檯應用程式的入口點。 // #include "stdafx.h" #include "Csqlpool.h" #include <iostream> using namespace std; Csqlpool *psql = Csqlpool::GetSqlPool(); DWORD WINAPI ThreadProc( LPVOID lpParameter); int _tmain(int argc, _TCHAR* argv[]) { if(!psql->IniSqlPool("127.0.0.1" , "root" ,"123",3306,10)) { cout<<"連線錯誤"<<endl; } HANDLE phan[2] ; DWORD threadid[2]; int n1 = 0, n2 = 100;; phan[0] = CreateThread( NULL , 0 , ThreadProc , &n1 , 0 , &threadid[0] ); phan[1] = CreateThread( NULL , 0 , ThreadProc , &n2 , 0 , &threadid[1] ); WaitForMultipleObjects( 2 , phan , true , INFINITE ); CloseHandle(phan[0]); CloseHandle(phan[1]); return 0; } DWORD WINAPI ThreadProc( LPVOID lpParameter) { int index = *(int *)lpParameter ; int i = 1; MYSQL *sql = psql->GetConnect(); string stemp = "insert into actor( actor_id , first_name , last_name,last_update )values(\""; string strsql; char str[10]; if ( psql->SelectDB(sql , "sakila") ) { while ( i != 100 ) { sprintf( str , "%d" , i+index ); strsql = stemp ; strsql += str; strsql += "\",\"0\",\"0\",\"0\")"; if(!sql) return 0; if(!psql->Query( sql ,strsql.c_str() )) { cout<<"add false"<<endl; } ++i; } psql->RelConnect(sql); } return 0; }