连接池为了解决频繁的创建、销毁所带来的系统开销。
简而言之,就是 自己先创建一定量的连接,然后在需要的时候取出一条连接使用。
当然如果你只有一个线程连接数据库,而且不是实时返回结果,那么你完全不必用连接池。
想一下网络大型游戏服务器,你就明白为什么需要连接池了。
自己敲代码写了一个简单的类,实现连接池,虽然没有mysql++那么强大,但是还是自己有收获。
Csqlpool.h 头文件实现如下:
#pragma once #include#include #include #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
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" #includeusing 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<<"连接错误"< 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"< RelConnect(sql); } return 0; }