您的位置:首页 > 运维架构 > Linux

Linux下操作Mysql类

2015-12-04 22:38 435 查看

操作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>

//MYSQL默认端口
#define DEFAULT_MYSQL_PORT 3306

using namespace std;

//连接数据库需要的所有信息 IP、数据库名、用户、用户密码、端口
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();

//注册MYSQL连接
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);

//查询有结果集返回的SQL语句
MYSQL_RES* SQLRetRes(const char *name,const char *pSql);
//查询无结果集返回的SQL语句
bool SQLNoRetRes(const char *name,const char *pSql);
//释放SQLRetRes返回的结果集
void FreeResult(MYSQL_RES *pRes);

//SELECT 返回string类型的动态数组
bool Select2Str(string name,string sql,vector<string> *strInfo);

//SELECT 返回多个string类型的动态数组
bool Select2Strs(string name,string sql,int fieldsNum,...);

private:

//连接信息结构,通过string唯一标志一个固定连接
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"

/*
*@funs:         构造函数
*/
LinkMysql::LinkMysql()
{
}

/*
*@funs:         释放数据库查询结果集
*@param pRes:   数据库查询结果集
*/
void LinkMysql::FreeResult(MYSQL_RES *pRes)
{
if(NULL!= pRes)
{
mysql_free_result(pRes);
}
}

/*
*@funs:         虚构函数,释放所有数据库连接资源和空间
*/
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);
}
}
}

/*
*@funs:         注册数据库连接信息
*@param name:   自定义连接名
*@param ip:     数据库IP地址
*@param db:     数据库名
*@param user:   连接数据库用户名
*@param pwd:    连接数据库密码
*@param port:   数据库PORT端口,默认为3306
*@ret:          true/注册成功   false/注册失败
*/
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;
}

/*
*@funs:             打印错误信息
*@param pMysql:     MYSQL连接资源
*/
void LinkMysql::PrintErrorMsg(MYSQL *pMysql)
{
cout<< mysql_error(pMysql)<< endl;
}

/*
*@funs:         连接name对应信息的数据库
*@param name:   自定义连接名
*@ret:          true/连接成功   false/连接失败
*/
bool LinkMysql::ConnectSingleMysql(string name)
{
bool bRet= false
4000
;
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;
}

/*
*@funs:         连接注册过的所有数据库信息
*@ret:          true/连接成功   false/连接失败
*/
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;
}

/*
*@funs:         返回结果集的query调用  SELECT...
*param name:    RegisterLink注册时命名的连接名
*param pSql:    执行的SQL语句
*@ret:          非NULL/执行成功  NULL/执行失败
*/
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) )
{
//保存结果集到本地并返回 返回后一定要用FreeResult释放结果
pRes= mysql_store_result(pMysql);
}
else
{
PrintErrorMsg(pMysql);
}
}
}
return pRes;
}

/*
*@funs:         无结果集返回的query调用 UPDATE INSERT CREATE
*param name:    RegisterLink注册时命名的连接名
*param pSql:    执行的SQL语句
*@ret:          true/执行成功   false/执行失败
*/
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;
}

/*
*@funs:         一个字段的查询结果保存至动态数组中(全部存储为字符串格式)
*param name:    RegisterLink注册时命名的连接名
*param sql:     执行的SQL语句
*param strInfo: 结果返回的动态数组指针
*@ret:          true/执行成功   false/执行失败
*/
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;
}

/*
*@funs:             多个字段的查询结果保存至多个动态数组中(全部存储为字符串格式)
*param name:        RegisterLink注册时命名的连接名
*param sql:         执行的SQL语句
*param fieldsNum:   返回查询的列数(和后面动态参数的个数一定要相等,否则会报段错误)
*param ...:         vector<string> * 类型的动态参数列表,存储查询后的数据
*@ret:              true/执行成功   false/执行失败
*/
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);

//当SQL执行后获取的列数不等于传入的fieldsNum时,取两者中较小值进行赋值操作
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

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux mysql c++ STL