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; //获取空闲线程 };
#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; }
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。