mysql c api簡單連接池

jopen 10年前發布 | 51K 次閱讀 連接池 數據庫連接池

連接池為了解決頻繁的創建、銷毀所帶來的系統開銷。

簡而言之,就是 自己先創建一定量的連接,然后在需要的時候取出一條連接使用。

當然如果你只有一個線程連接數據庫,而且不是實時返回結果,那么你完全不必用連接池。

想一下網絡大型游戲服務器,你就明白為什么需要連接池了。

自己敲代碼寫了一個簡單的類,實現連接池,雖然沒有mysql++那么強大,但是還是自己有收獲。

 

Csqlpool.h 頭文件實現如下:

    #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;    //獲取空閑線程  
    };  

 

Csqlpool.cpp 實現如下:
    #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;  
}  
來自:http://blog.csdn.net/midle110/article/details/19564463
 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!