Linux下操作Mysql类

本文介绍了一个Mysql数据库操作类的设计与实现,包括数据库连接、注册、查询等功能,使用了多个实例展示如何通过该类进行数据库操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值