1. 程式人生 > >mysql c api簡單連線池

mysql c api簡單連線池

連線池為了解決頻繁的建立、銷燬所帶來的系統開銷。

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

當然如果你只有一個執行緒連線資料庫,而且不是實時返回結果,那麼你完全不必用連線池。

想一下網路大型遊戲伺服器,你就明白為什麼需要連線池了。

自己敲程式碼寫了一個簡單的類,實現連線池,雖然沒有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;
}