操作Mysql类主要满足以下需求:
- 可定制:可个性化连接MYSQL数据库连接资源的名称
- 多个数据库连接并存,通过连接名称唯一标记。类似Xshell
- 统一接口:可将SELECT查库操作结果统一成返回多个
vector<string>
动态数组形式完成调用
Talk is cheap, show me the code !!!
MysqlApi.h
#ifndef __MYSQL_API__
#define __MYSQL_API__
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <iostream>
#include <string>
#include <vector>
#include <map>
#include <mysql/mysql.h>
#define DEFAULT_MYSQL_PORT 3306
using namespace std;
struct LinkInfo
{
string ip;
string db;
string user;
string pwd;
unsigned short port;
LinkInfo(string ip_, string db_, string user_, string pwd_, unsigned short port_):ip(ip_),db(db_),\
user(user_),pwd(pwd_),port(port_){}
};
class LinkMysql
{
public:
LinkMysql();
~LinkMysql();
bool RegisterLink(string name,string ip,string db,string user, string pwd,unsigned short port= DEFAULT_MYSQL_PORT);
bool ConnectMysql();
bool ConnectSingleMysql(string name);
void PrintErrorMsg(MYSQL *pMysql);
MYSQL_RES* SQLRetRes(const char *name,const char *pSql);
bool SQLNoRetRes(const char *name,const char *pSql);
void FreeResult(MYSQL_RES *pRes);
bool Select2Str(string name,string sql,vector<string> *strInfo);
bool Select2Strs(string name,string sql,int fieldsNum,...);
private:
typedef map<string, pair<LinkInfo *, MYSQL *> > mp_mysql;
typedef map<string, pair<LinkInfo *, MYSQL *> >::iterator mp_mysql_iter;
mp_mysql mp_link;
};
#endif
MysqlApi.cpp
#include <stdlib.h>
#include "MysqlApi.h"
LinkMysql::LinkMysql()
{
}
void LinkMysql::FreeResult(MYSQL_RES *pRes)
{
if(NULL!= pRes)
{
mysql_free_result(pRes);
}
}
LinkMysql::~LinkMysql()
{
for(mp_mysql_iter it= mp_link.begin();it!= mp_link.end();it++)
{
if(it->second.second!= NULL)
{
mysql_close(it->second.second);
}
if(it->second.first!= NULL)
{
free(it->second.first);
}
}
}
bool LinkMysql::RegisterLink(string name,string ip,string db,string user, string pwd,unsigned short port)
{
bool bRet= false;
LinkInfo *pInfo= new LinkInfo(ip,db,user,pwd,port);
if(pInfo!= NULL)
{
mp_link[name].first= pInfo;
mp_link[name].second= NULL;
bRet= true;
}
return bRet;
}
void LinkMysql::PrintErrorMsg(MYSQL *pMysql)
{
cout<< mysql_error(pMysql)<< endl;
}
bool LinkMysql::ConnectSingleMysql(string name)
{
bool bRet= false;
mp_mysql_iter it= mp_link.find(name);
if(it!= mp_link.end())
{
if(NULL!= (it->second.second= mysql_real_connect(mysql_init(NULL),it->second.first->ip.c_str(),\
it->second.first->user.c_str(),it->second.first->pwd.c_str(),it->second.first->db.c_str(),0,NULL,0)))
{
bRet= true;
}
}
return bRet;
}
bool LinkMysql::ConnectMysql()
{
bool bRet= true;
for(mp_mysql_iter it= mp_link.begin();it!= mp_link.end();it++)
{
if(!ConnectSingleMysql(it->first))
{
bRet= false;
}
}
return bRet;
}
MYSQL_RES* LinkMysql::SQLRetRes(const char *name,const char *pSql)
{
MYSQL_RES *pRes = NULL;
MYSQL* pMysql= NULL;
mp_mysql_iter it= mp_link.find(name);
if(it!= mp_link.end())
{
if((it->second.second!= NULL) || (it->second.second== NULL && ConnectSingleMysql(name)))
{
pMysql= it->second.second;
if( !mysql_query(pMysql,pSql) )
{
pRes= mysql_store_result(pMysql);
}
else
{
PrintErrorMsg(pMysql);
}
}
}
return pRes;
}
bool LinkMysql::SQLNoRetRes(const char *name,const char *pSql)
{
bool bRet= false;
MYSQL_RES *pRes = NULL;
MYSQL* pMysql= NULL;
mp_mysql_iter it= mp_link.find(name);
if(it!= mp_link.end())
{
if((it->second.second!= NULL) || (it->second.second== NULL && ConnectSingleMysql(name)))
{
pMysql= it->second.second;
if(!mysql_query(pMysql,pSql))
{
bRet= true;
}
else
{
PrintErrorMsg(pMysql);
}
}
}
return bRet;
}
bool LinkMysql::Select2Str(string name,string sql,vector<string> *strInfo)
{
MYSQL_RES* pRes= SQLRetRes(name.c_str(),sql.c_str());
MYSQL_ROW row;
if(strInfo== NULL)
return false;
while(row= mysql_fetch_row(pRes))
{
(*strInfo).push_back(row[0]);
}
FreeResult(pRes);
return true;
}
bool LinkMysql::Select2Strs(string name,string sql,int fieldsNum,...)
{
int i= 0;
va_list val;
MYSQL_ROW row;
if(fieldsNum<= 0)
return false;
MYSQL_RES* pRes= SQLRetRes(name.c_str(),sql.c_str());
int num= mysql_num_fields(pRes);
int realNum= (num>= fieldsNum)?num:fieldsNum;
vector<string>* argsV[realNum];
va_start(val, fieldsNum);
for(i= 0;i< realNum;i++)
{
argsV[i]= va_arg(val, vector<string> *);
}
va_end(val);
while(row= mysql_fetch_row(pRes))
{
for(i= 0;i< realNum;i++)
{
(*argsV[i]).push_back(row[i]);
}
}
FreeResult(pRes);
return true;
}
示例程序:main.cpp
#include <iostream>
#include "MysqlApi.h"
using namespace std;
int main()
{
LinkMysql test;
test.RegisterLink("link1","192.168.1.1","dbName","user","password");
test.RegisterLink("link2","192.168.1.2","dbName","user","password");
if(!test.ConnectMysql())
{
cout<< "connect mysql error !"<< endl;
}
vector<string> strInfo;
vector<string> str2Info;
if(test.Select2Strs("link1","SELECT EMP_HEAD,EMP_NO FROM EMP WHERE IM_ID< 100",2,&strInfo,&str2Info))
{
for(int i= 0;i< strInfo.size();i++)
{
cout<< "str1: "<< strInfo[i]<< "\tstr2:"<< str2Info[i]<< endl;
}
}
return 1;
}
编译:g++ main.cpp MysqlApi.cpp -L./ -lmysqlclient
以上代码仅为个人愚见,如有疑问请各位看官指出。tks