mysql连接池搭的api_MYSQL C API 封装和MYSQL连接池

注意:

1、如果查询到的数据有多条需要把SQL语句重复执行。

2、执行完毕select语句并没有数据的时候请注意调用ClearResult函数进行记录集指针清理,不然下次同样的SQL执行会得到自己不要的数据。如果上次SQL语句和本次SQL语句不一样的话不存在这样的问题,内部会根据SQL对比不同的时候会自动清理旧的记录集数据。

代码:

mysql 类封装 头文件源码如下:

#pragma once

#include #include #include #include #include #include #include "mysql/mysql.h"

#include

#include #include #pragma comment(lib,"wsock32.lib")

#pragma comment(lib, "mysql_api/libmysql.lib ")

//mysql参考文档

/*

*本文件是提供一些经常使用接口

*时间:2014.07.31

*作者:吴建华

*邮箱:564154394@qq.com

*/

/*

*modify:

*2016.11.07

*吴建华

* 修改事项:

* 1、mysql获取记录集函数不支持多线程所以增加了锁解决了记录集被修改的bug

* 2、增加了mysql连接池类 并希望大量插入数据库的时候使用mysql事务处理方式

*/

/*

*MYSQL 字段类参照表

*整理者:吴建华

*/

/************************************************************************

类型值类型描述

MYSQL_TYPE_TINYTINYINT字段

MYSQL_TYPE_SHORTSMALLINT字段

MYSQL_TYPE_LONGINTEGER或INT字段

MYSQL_TYPE_INT24MEDIUMINT字段

MYSQL_TYPE_LONGLONGBIGINT字段

MYSQL_TYPE_DECIMALDECIMAL或NUMERIC字段

MYSQL_TYPE_NEWDECIMAL精度数学DECIMAL或NUMERIC

MYSQL_TYPE_FLOATFLOAT字段

MYSQL_TYPE_DOUBLEDOUBLE或REAL字段

MYSQL_TYPE_BITBIT字段

MYSQL_TYPE_TIMESTAMPTIMESTAMP字段

MYSQL_TYPE_DATEDATE字段

MYSQL_TYPE_TIMETIME字段

MYSQL_TYPE_DATETIMEDATETIME字段

MYSQL_TYPE_YEARYEAR字段

MYSQL_TYPE_STRINGCHAR字段

MYSQL_TYPE_VAR_STRINGVARCHAR字段

MYSQL_TYPE_BLOBBLOB或TEXT字段(使用max_length来确定最大长度)

MYSQL_TYPE_SETSET字段

MYSQL_TYPE_ENUMENUM字段

MYSQL_TYPE_GEOMETRYSpatial字段

MYSQL_TYPE_NULLNULL-type字段

MYSQL_TYPE_CHAR不再重视,用MYSQL_TYPE_TINY取代

************************************************************************/

/*

*用于变参类型 如:%d %s两种类型

*

*/

#define DATA_TYPE_INT4//整型

#define DATA_TYPE_CHARPTR1//char*类型

#define DATA_TYPE_INVALID0//无效类型

/*

*select接口区分字符类型和cstring类型

*/

enum e_strType{e_char=0, e_cstring};

/*

*CTools是提供一些常用的接口类

*时间:2014.07.31

*作者:吴建华

*/

namespace _TOOLS_

{

static CMutex g_mtxmysql;//mysql操作对象的互斥对象

static CMutex g_mtxMysqlPool;//mysql连接池的互斥对象

class CTools

{

public:

MYSQLMysql;//mysql对象

~CTools()

{

mysql_close( &Mysql );

};

CTools()

{

m_pResult = NULL;

m_bOpen = false;

};

/*

*数据库初始化操作

*

*参数:

*pIP:数据库IP地址

*pUser:数据库用户名

*pPwd:数据库密码

*pDatabase:数据库名称

*

*返回值:

*返回false表示初始化失败,true表示初始化成功

*

*/

bool initmysql(const char* pIP, const char* pUser, const char* pPwd, const char* pDatabase, unsigned short nPort = 3306 );

/*

*执行数据库查询功能(带_s的标识支持CSting类型,不带的支持char*类型)

*参数:

*pSQL:SQL语句

*...:变参返回查询到的数据

*返回值:

*返回false表示数据库已经获取完毕,true表示数据还没有获取完毕

*/

bool select_sql_beack(__in const char *pSQL, __out ...);

bool select_sql_beack_s(__in const char *pSQL, __out ...);

/*

*修改/插入/删除功能

*参数:

*pSQL:SQL语句

*返回值:

*返回false表示执行失败,true表示执行成功

*

*/

bool update_sql(__in const char *pSQL);

bool insert_sql(__in const char *pSQL);

bool delete_sql(__in const char *pSQL);

/*

*执行查询SQL语句获取查询的数据

*

*参数:

*pSQL:sql语句

*ap:变参,是指输出查询到的数据

*

*返回值:

*返回false表示不是无效字符,非true表示是无效字符

*/

//打断上一次执行(意思就是不支持嵌套,嵌套可以使用上面的Select)

bool SelectBeack(__in const char *pSQL, e_strType, __out va_list ap);

/*

*清理记录集指针数据

*

*/

/*

*获取 MYSQL连接状态

*

*返回值:

*返回true 表示没有断开 返回false 表示mysql连接已经断开

*

*/

bool GetMysqlConnectStatus()

{

if (m_bOpen)

{

if( mysql_ping(&Mysql) == 0)//处于连接状态中

{

return true;

}

}

return m_bOpen;

}

/*

*清理查询后有多余的数据 最好执行sql语句后获取到所有需要数据后调用次接口清理

*/

void ClearResult()

{

if ( m_pResult!= NULL )

{

mysql_free_result(m_pResult);

m_pResult = NULL;

m_strOldSql = "";

}

//m_Lastmysql.initdata();

}

/*

*关闭mysql连接

*/

void CloseMysql(){

//if ( _pMysql )

{

mysql_close( &Mysql );

//_pMysql = NULL;

}

}

//是否自动提交

void AutoCommitSQL(BOOL bAuto = TRUE);

private:

bool execute(const char* pSQL);

private:

//MYSQL_INFO m_Lastmysql;

CString m_strOldSql;//旧的SQL语句

MYSQL_RES *m_pResult;//记录集

bool m_bOpen;

//公共接口

public:

static CString GetBinPath();

static WCHAR* ToWChar(char *str);

};

/************************************************************************/

/*MYSQL 连接池 */

/************************************************************************/

class mysql_connection_pool

{

public:

~mysql_connection_pool();

//单例模式

static mysql_connection_pool *GetInstance();

//初始化连接

size_t InitConnection(int nInitialSize=1);

//设置mysql信息

void SetMysqlInfo(const char* pIP,

const char* pUser,

const char* pPwd,

const char* pDatabase,

unsigned short nPort /* = 3306 */);

//获取msyql操作对象

CTools *GetConnection();

//回收连接对象

void ReleaseConnection(CTools * pObject);

//销毁连接池

void DestoryConnPool();

protected:

mysql_connection_pool();

private:

char m_szIP[128];

char m_szUser[128];

char m_szPwd[128];

char m_szDatabase[128];

short m_snPort;

std::queuethe_queue;

CMutex the_mutex;

};

}

mysql 操作类封装 实现文件源码如下:

#include "stdafx.h"

#include "tools.h"

#include using namespace _TOOLS_;

bool CTools::initmysql(const char* pIP,

const char* pUser,

const char* pPwd,

const char* pDatabase,

unsigned short nPort /* = 3306 */ )

{

//mysql初始化

mysql_init(&Mysql);

//连接数据库

if (!mysql_real_connect(&Mysql, pIP, pUser, pPwd, pDatabase, nPort, NULL, CLIENT_MULTI_STATEMENTS))

{

m_bOpen = false;

return m_bOpen;

}

mysql_query(&Mysql,"SET NAMES 'GBK'");

mysql_query(&Mysql, "set global max_connections=4000");//设置最大连接数量(mysql服务器默认为151 所以这里找到配置文件 只有这个办法咯)

mysql_options(&Mysql,MYSQL_READ_DEFAULT_GROUP,"IMServer");

m_bOpen = true;

return m_bOpen;

}

bool CTools::select_sql_beack(__in const char *pSQL, __out ...)

{

va_list ap;

va_start( ap, pSQL );

bool bRet = SelectBeack( pSQL,e_char,ap );

va_end( ap );

return bRet;

}

bool CTools::select_sql_beack_s(__in const char *pSQL, __out ...)

{

va_list ap;

va_start( ap, pSQL );

bool bRet = SelectBeack( pSQL,e_cstring,ap );

va_end( ap );

return bRet;

}

bool CTools::SelectBeack(__in const char *pSQL, e_strType nstrType, __out va_list ap)

{

MYSQL_ROW row;//数据

MYSQL_RES *pResult = NULL;//记录集指针

unsigned int num_fields;//字段个数

MYSQL_FIELD* pFields;//字段类型信息

if (!m_bOpen)

{

return false;

}

try

{

if (m_strOldSql.CompareNoCase(pSQL) != 0)

{

//没有查询过SQL新建查询

ClearResult();//清理记录集数据

g_mtxmysql.Lock();

if(!(mysql_query(&Mysql, pSQL) == 0) )

{

//查询失败

g_mtxmysql.Unlock();

return false;

}

//查询数据

pResult = mysql_use_result(&Mysql);

g_mtxmysql.Unlock();

int nCount = mysql_field_count(&Mysql);

if (!pResult)

{

return false;

}

m_strOldSql.Format("%s", pSQL);

}

else

{

pResult = m_pResult;

}

int *pnType = NULL;

CString *pstrType = NULL;

char * pszType = NULL;

num_fields = mysql_num_fields(pResult);

//获取一条数据

if(!(row = mysql_fetch_row(pResult)))

{

ClearResult();

return false;

}

for (unsigned int i=0; itype;

switch(nfieldtype)

{

//转整型 //这里有小数点的还没有做处理 需要进一步处理

case MYSQL_TYPE_SHORT:

case MYSQL_TYPE_LONG:

case MYSQL_TYPE_INT24:

case MYSQL_TYPE_LONGLONG:

case MYSQL_TYPE_FLOAT:

case MYSQL_TYPE_DOUBLE:

{

pnType = va_arg(ap, int *);

if (pnType == NULL)

{

break;

}

if (row[i] == NULL)

{

*pnType = 0;

}

else

{

*pnType = atoi(row[i]);

}

}

break;

//转字符类型

case MYSQL_TYPE_DATE:

case MYSQL_TYPE_TIME:

case MYSQL_TYPE_DATETIME:

case MYSQL_TYPE_STRING:

case MYSQL_TYPE_TINY:

case MYSQL_TYPE_VAR_STRING:

{

if (nstrType == e_cstring)

{

pstrType = va_arg(ap,CString *);

if (pstrType == NULL)

{

break;

}

if (row[i] == NULL)

{

*pstrType = "";

}

else

{

*pstrType = row[i];

}

}

else

{

pszType = va_arg(ap,char *);

if (pszType == NULL)

{

break;

}

if (row[i] == NULL)

{

pszType[0] = 0;

}

else

{

strcpy(pszType,row[i]);

}

}

}

break;

default:

{

// 我未预料到的类型。把参数指针向后移;

pszType = va_arg( ap, char *);

}

break;

}

}

}

catch (...)

{

ClearResult();

return false;

}

m_pResult = pResult;

return true;

}

bool CTools::execute(const char* pSQL)

{

ASSERT(pSQL);

try

{

int nRet = mysql_query(&Mysql, pSQL);

if ( nRet != 0 )

{

const char* pError=NULL;

pError = mysql_error(&Mysql);

TRACE("MYSQL错误提示%s\r\n",pError);

return false;

}

}

catch (...)

{

return false;

}

return true;

}

bool CTools::delete_sql(__in const char *pSQL)

{

return execute(pSQL);

}

bool CTools::update_sql(const char *pSQL)

{

return execute(pSQL);

}

bool CTools::insert_sql(const char *pSQL)

{

return execute(pSQL);

}

void _TOOLS_::CTools::AutoCommitSQL(BOOL bAuto /*= TRUE*/)

{

mysql_autocommit(&Mysql, bAuto);

}

CString CTools::GetBinPath()

{

CString sPath;

GetModuleFileName(NULL, sPath.GetBufferSetLength(MAX_PATH + 1), MAX_PATH);

sPath.ReleaseBuffer();

int nPos;

nPos = sPath.ReverseFind('\\');

sPath = sPath.Left(nPos);

return sPath;

}

WCHAR* CTools::ToWChar(char *str)

{

static WCHAR buffer[1024];

memset(buffer, 0, 1024);

MultiByteToWideChar(CP_ACP, 0, str, strlen(str), buffer, 1024);

return buffer;

}

/************************************************************************/

/*MYSQL 连接池 */

/************************************************************************/

mysql_connection_pool::mysql_connection_pool()

{

}

mysql_connection_pool::~mysql_connection_pool()

{

DestoryConnPool();

}

mysql_connection_pool * mysql_connection_pool::GetInstance()

{

static mysql_connection_pool object;

return &object;

}

CTools * mysql_connection_pool::GetConnection()

{

g_mtxMysqlPool.Lock();

CTools *pMysqlobject = NULL;

if (the_queue.empty())

{

g_mtxMysqlPool.Unlock();

return pMysqlobject;

}

pMysqlobject = the_queue.front();

the_queue.pop();

g_mtxMysqlPool.Unlock();

return pMysqlobject;

}

size_t _TOOLS_::mysql_connection_pool::InitConnection(int nInitialSize/*=1*/)

{

ASSERT(nInitialSize > 0);

g_mtxMysqlPool.Lock();

for ( int i=0; iinitmysql(m_szIP, m_szUser, m_szPwd, m_szDatabase, m_snPort))

{

delete pObject;

pObject = NULL;

continue;

}

/*

* 使用者 批量执行SQL前需要执行START TRANSACTION语法使得事物开启

*

* 使用者 在需要批量SQL执行完成后方可执行COMMIT语法 使得数据一并提交

*/

pObject->AutoCommitSQL(FALSE);//关闭自动调教 采用事物提交

the_queue.push(pObject);

}

size_t nSize = the_queue.size();

g_mtxMysqlPool.Unlock();

return nSize;

}

void _TOOLS_::mysql_connection_pool::SetMysqlInfo(const char* pIP, const char* pUser, const char* pPwd, const char* pDatabase, unsigned short nPort /* = 3306 */)

{

ASSERT(pIP != NULL);

ASSERT(pUser != NULL);

ASSERT(pPwd != NULL);

ASSERT(pDatabase != NULL);

g_mtxMysqlPool.Lock();

memcpy(m_szIP, pIP, strlen(pIP));

memcpy(m_szUser, pUser, strlen(pUser));

memcpy(m_szPwd, pPwd, strlen(pPwd));

memcpy(m_szDatabase, pDatabase, strlen(pDatabase));

m_snPort = nPort;

g_mtxMysqlPool.Unlock();

}

void mysql_connection_pool::ReleaseConnection(CTools * pObject)

{

ASSERT(pObject);

g_mtxMysqlPool.Lock();

the_queue.push(pObject);

g_mtxMysqlPool.Unlock();

}

void mysql_connection_pool::DestoryConnPool() {

g_mtxMysqlPool.Lock();

if (!the_queue.empty())

{

CTools *pMysqlobject = the_queue.front();

the_queue.pop();

pMysqlobject->insert_sql("COMMIT");

delete pMysqlobject;

pMysqlobject = NULL;

}

g_mtxMysqlPool.Unlock();

}

下次在写如何使用这个类来进行mysql读写(异步读写mysql,事务处理实现批量插入数据库,连接池的使用方式)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值