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
相关文章推荐
- MySQL中的integer 数据类型
- Linux socket 初步
- MySQL存储过程
- 使用C++实现JNI接口需要注意的事项
- linux lsof详解
- linux 文件权限
- Linux 执行数学运算
- 10 篇对初学者和专家都有用的 Linux 命令教程
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- mysql中int、bigint、smallint 和 tinyint的区别与长度
- mysql load data 导出、导入 csv
- source命令执行SQL脚本文件
- Ubuntu Linux使用体验