在有大量節點訪問的數據庫設計中,經常要使用到連接池來管理所有的連接.
一般方法是:建立兩個連接句柄隊列,空閑的等待使用的隊列和正在使用的隊列.
當要查詢時先從空閑隊列中獲取一個句柄,插入到正在使用的隊列,再用這個句柄做數據庫操作,完畢后一定要從使用隊列中刪除,再插入到空閑隊列.
代碼如下:
MySQLMan.h
// MySQLMan.h: interface for the CMySQLMan class.
//
//////////////////////////////////////////////////////////////////////
#include <mysql.h>
#pragma comment(lib,"libmySQL.lib")
#include <list>
typedef std::list<MYSQL *> CONNECTION_HANDLE_LIST;
typedef std::list<MYSQL *>::iterator ITER_CONNECTION_HANDLE_LIST;
#define CONNECTION_NUM 10 //同時打開的連接數
class CMySQLMan
{
public:
CMySQLMan();
CMySQLMan(const char *host, const char *user, const char *password, const char *db, unsigned int port=3306);
virtual ~CMySQLMan();
public:
bool ConnectDB(); //連接數據庫
MYSQL_RES* SelectRecord(const char *szSql); //選擇記錄,返回結果集
bool SelectDB(const char *szDB); //選擇數據庫
bool UpdateRecord(const char *szSql); //更新記錄
bool InsertRecord(const char *szSql); //插入記錄
bool DelRecord(const char *szSql); //刪除記錄
BOOL IsEnd(MYSQL_RES *myquery); //是否最后
void SeekData(MYSQL_RES *myquery, int offset); //查找指定數據
void FreeRecord(MYSQL_RES *myquery); //釋放結果集
unsigned int GetFieldNum(MYSQL_RES *myquery); //得到字段數
MYSQL_ROW GetRecord(MYSQL_RES *myquery); //得到結果(一個記錄)
my_ulonglong GetRowNum(MYSQL_RES *myquery); //得到記錄數
char* OutErrors(MYSQL* pMySql); //輸出錯誤信息
char* GetState(); //服務器狀態
char* GetServerInfo(); //服務器信息
int GetProtocolInfo(); //協議信息
char* GetHostInfo(); //主機信息
char* GetClientInfo(); //客戶機信息
char* GetFieldName(MYSQL_RES *myquery, int FieldNum); //字段名
bool LockTable(const char *TableName, const char *Priority); //對特定表加鎖
bool UnlockTable(); //解鎖
bool SetCharset();
//int CreateDB(char *db); //創建數據庫,返回錯誤信息
//int DropDB(char *db); //刪除數據庫,返回錯誤信息
MYSQL* GetIdleMySql(); //提取一個空閑句柄供使用
void SetIdleMysql(MYSQL* pMySql); //從使用隊列中釋放一個使用完畢的句柄,插入到空閑隊列
public:
//MYSQL m_mysql; //數據庫連接句柄
MYSQL_ROW m_row; //記錄集(單行)
MYSQL_FIELD *m_field; //字段信息(結構體)
//創建兩個隊列
CONNECTION_HANDLE_LIST m_lsBusyList; //正在使用的連接句柄
CONNECTION_HANDLE_LIST m_lsIdleList; //未使用的連接句柄
CRITICAL_SECTION m_csList;
public:
char m_host[20]; //主機
char m_user[20]; //用戶名
char m_password[20]; //密碼
char m_db[20]; //數據庫名
unsigned int m_port; //端口
};
MySQLMan.cpp
// MySQLMan.cpp: implementation of the MySQLMan class.
//
//////////////////////////////////////////////////////////////////////
#include "StdAfx.h"
#include "MySQLMan.h"
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMySQLMan::CMySQLMan()
{
}
CMySQLMan::CMySQLMan(const char *host, const char *user, const char *password, const char *db, unsigned int port/* =3306 */)
{
strcpy(m_host, host);
strcpy(m_user, user);
strcpy(m_password, password);
strcpy(m_db, db);
m_port = port;
InitializeCriticalSection(&m_csList);
}
CMySQLMan::~CMySQLMan()
{
for (ITER_CONNECTION_HANDLE_LIST iter=m_lsBusyList.begin(); iter != m_lsBusyList.end(); iter++)
{
mysql_close((*iter));
}
for (ITER_CONNECTION_HANDLE_LIST iter=m_lsIdleList.begin(); iter != m_lsIdleList.end(); iter++)
{
mysql_close((*iter));
}
DeleteCriticalSection(&m_csList);
}
bool CMySQLMan::ConnectDB()
{
//同時打開CONNECTION_NUM個連接
try
{
for (int i=0; i<CONNECTION_NUM; ++i)
{
MYSQL *pMySql = mysql_init((MYSQL*)NULL);
if (pMySql != NULL)
{
if (!mysql_real_connect(pMySql,m_host,m_user,m_password,m_db,m_port,NULL,0))
{
OutErrors(pMySql);
return false;
}
m_lsIdleList.push_back(pMySql);
}
}
}
catch (...)
{
return false;
}
return true;
}
MYSQL* CMySQLMan::GetIdleMySql()
{
MYSQL* pMySql = NULL;
EnterCriticalSection(&m_csList);
if (m_lsIdleList.size() > 0)
{
pMySql = m_lsIdleList.front();
m_lsIdleList.pop_front();
m_lsBusyList.push_back(pMySql);
}
else
{
pMySql = NULL;
}
LeaveCriticalSection(&m_csList);
return pMySql;
}
void CMySQLMan::SetIdleMysql(MYSQL* pMySql)
{
EnterCriticalSection(&m_csList);
m_lsBusyList.remove(pMySql);
m_lsIdleList.push_back(pMySql);
LeaveCriticalSection(&m_csList);
}
MYSQL_RES* CMySQLMan::SelectRecord(const char *szSql)
{
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return NULL;
}
if(mysql_query(pMySql,szSql))
return NULL;
MYSQL_RES *myquery = NULL;
myquery = mysql_store_result(pMySql);
SetIdleMysql(pMySql);
return myquery;
}
bool CMySQLMan::InsertRecord(const char *szSql)
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
if(mysql_query(pMySql,szSql))
{
bRet = true;
}
SetIdleMysql(pMySql);
return bRet;
}
bool CMySQLMan::UpdateRecord(const char *szSql)
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
if(mysql_query(pMySql,szSql))
{
bRet = true;
}
SetIdleMysql(pMySql);
return bRet;
}
bool CMySQLMan::DelRecord(const char *szSql)
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
if(mysql_query(pMySql,szSql))
{
bRet = true;
}
SetIdleMysql(pMySql);
return bRet;
}
bool CMySQLMan::SelectDB(const char *szDB)
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
if (mysql_select_db(pMySql,szDB))
bRet = false;
else
bRet = true;
SetIdleMysql(pMySql);
return bRet;
}
my_ulonglong CMySQLMan::GetRowNum(MYSQL_RES *myquery)
{
return mysql_num_rows(myquery);
}
MYSQL_ROW CMySQLMan::GetRecord(MYSQL_RES *myquery)
{
m_row = mysql_fetch_row(myquery);
return m_row;
}
unsigned int CMySQLMan::GetFieldNum(MYSQL_RES *myquery)
{
return mysql_num_fields(myquery);
}
void CMySQLMan::FreeRecord(MYSQL_RES *myquery)
{
mysql_free_result(myquery);
}
//int CMySQLMan::CreateDB(char *db)
//{
// return mysql_create_db(&m_mysql,db);
//}
void CMySQLMan::SeekData(MYSQL_RES *myquery, int offset)
{
mysql_data_seek(myquery,offset);
}
char * CMySQLMan::OutErrors(MYSQL *pMySql)
{
return const_cast<char *>(mysql_error(pMySql));
}
BOOL CMySQLMan::IsEnd(MYSQL_RES *myquery)
{
return mysql_eof(myquery);
}
char* CMySQLMan::GetFieldName(MYSQL_RES *myquery, int FieldNum)
{
m_field = mysql_fetch_field_direct(myquery, FieldNum);
return m_field->name;
}
char * CMySQLMan::GetClientInfo()
{
return const_cast<char *>(mysql_get_client_info());
}
char* CMySQLMan::GetHostInfo()
{
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return NULL;
}
return const_cast<char *>(mysql_get_host_info(pMySql));
}
int CMySQLMan::GetProtocolInfo()
{
int iRet = 0;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return NULL;
}
iRet = mysql_get_proto_info(pMySql);
SetIdleMysql(pMySql);
return iRet;
}
char* CMySQLMan::GetServerInfo()
{
static char szRet[1024];
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return NULL;
}
_tcscpy(szRet, const_cast<char *>(mysql_get_server_info(pMySql)));
SetIdleMysql(pMySql);
return szRet;
}
char* CMySQLMan::GetState()
{
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return NULL;
}
static char szRet[1024];
_tcscpy(szRet,const_cast<char *>(mysql_stat(pMySql)));
SetIdleMysql(pMySql);
return szRet;
}
bool CMySQLMan::SetCharset()
{
bool bRet = false;
char szSql[50];
strcpy(szSql, "set names gb2312");
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
if (mysql_query(pMySql, szSql))
bRet = true;
SetIdleMysql(pMySql);
return bRet;
}
//LOCK TABLES tbl1 READ, tbl2 WRITE
bool CMySQLMan::LockTable(const char *TableName, const char *Priority)
{
bool bRet = false;
char szSql[50];
sprintf(szSql, "LOCK TABLES %s %s", TableName, Priority);
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
if (mysql_query(pMySql, szSql))
bRet = true;
SetIdleMysql(pMySql);
return bRet;
}
bool CMySQLMan::UnlockTable()
{
bool bRet = false;
MYSQL *pMySql = GetIdleMySql();
if (pMySql == NULL)
{
return false;
}
if(mysql_query(pMySql,"UNLOCK TABLES"))
bRet = true;
SetIdleMysql(pMySql);
return bRet;
}
posted on 2008-02-21 15:10
水 閱讀(4541)
評論(1) 編輯 收藏 引用 所屬分類:
socket編程