数据库连接池DBPool分析(三):Mysql连接控制:MysqlObj

这个class的设计是这样的,初始化的时候并不建立连接,仅仅简单地初始化成员变量(IP地址,User,password等),而是单独提供一个Connect函数来建立连接,连接的时候把mysql的编码设置为gb2312,关闭连接也有一个Close函数,析构的时候会调用Close.
Dump函数是用来debug用的,将m_pMysql指针指向的值打印出来。

MysqlObj并不使用QueryResult作为它的成员,只有在ExecuteSql的时候才简单的使用QueryResult的引用来接收查询结果。
如果是写SQL的话,也就是INSERT INTO,UPDATE INTO,DELETE 的话,由于会有受影响行数和插入id,所以需要使用成员变量m_iAffectedRows, m_iInsertId;来接收。


#ifndef _MYSQL_OBJ_H
#define _MYSQL_OBJ_H

#include <mysql/mysql.h>
#include "QueryResult.h"
#include "debug.h"

// 设置一个标志,函数参数列表当中带有OUT的就是输出引用,带有IN的就是输入参数
#define OUT
#define IN

class MysqlObj
{
 public:
    MysqlObj(string HostIP, string pUser, string pPassword, string pDBname, unsigned iPort);
    virtual ~MysqlObj();
    // Dump指的是把m_pMysql的指针指向的值打印出来
    void Dump() const;

    string ErrorMessage();

    // 根据成员变量来建立MYSQL连接
    bool Connect();
    bool Reconnect();
    void Close();

    int SelectDB(const char* pDatabase);
    int ExecuteSql(IN const char* pSql, OUT QueryResult& vecResult);

    //执行SQL受到影响的行数
    unsigned long long AffectedRows() const;
    unsigned long long InsertId() const;

    //返回MYSQL的指针
    MYSQL* get() const;

    //测试mysql服务器是否存活
    bool Ping() const;

 private:
    // MYSQL代表了一条TCP连接
    MYSQL* m_pMysql;

    // 连接必备的参数:IP地址,用户,密码,数据库名称,端口号
    string m_strHost;
    string m_strUser;
    string m_strPassword;
    string m_strDBname;
    unsigned m_iPort;

    //错误信息
    string m_strErrorMessage;
    // 
    unsigned long long m_iAffectedRows;
    unsigned long long m_iInsertId;
};

#endif /* MYSQL_OBJ_H */

================================================
2015年10月18号修改
为了使用shared_ptr来操作指针,增加了代码:
虽然我的ubuntu用的是gcc 4.8.4 但是考虑到centos的gcc版本可能不支持C++11的shared_ptr,所以直接使用boost::shared_ptr

typedef boost::shared_ptr<MysqlObj>MysqlObjPtr;

#include "../include/mysql_obj.h"
#include <assert.h>
#include <cstring>

MysqlObj::MysqlObj(string host, string user, string password, string dbname, unsigned port)
: m_strHost(host), m_strUser(user), m_strPassword(password), m_strDBname(dbname), m_iPort(port)
{
    m_pMysql = NULL;
}

MysqlObj::~MysqlObj()
{
    Close();
}

void MysqlObj::Dump() const
{
    printf("m_pMysql=%p", m_pMysql);
}

string MysqlObj::ErrorMessage()
{
    m_strErrorMessage = "";
    if ( m_pMysql ) 
    {
        string pMessage = mysql_error(m_pMysql);
        m_strErrorMessage = pMessage;
    }
    return m_strErrorMessage;
}

bool MysqlObj::Connect()
{
    m_pMysql = mysql_init(NULL);
    if ( NULL == m_pMysql )
    {
        return false;
    }

    char cValue = 1;    
    if ( 0 != mysql_options(m_pMysql, MYSQL_OPT_RECONNECT, (char *)&cValue) )   
    {
        ErrorMessage();
        Close();
        return false;
    }

    if ( NULL == mysql_real_connect(m_pMysql, m_strHost.c_str(), m_strUser.c_str(), m_strPassword.c_str(), m_strDBname.c_str(), m_iPort, NULL, 0) ) 
    {
        ErrorMessage();
        Close();
        return false;
    }
    mysql_set_character_set(m_pMysql, "gb2312");
    return true;
}

bool MysqlObj::Reconnect() 
{
    Close();
    m_pMysql = mysql_init(NULL);
    if ( NULL == m_pMysql ) 
    {
        return false;
    }
    if ( NULL == mysql_real_connect(m_pMysql, 
                m_strHost.size()?m_strHost.c_str():NULL, 
                m_strUser.size()?m_strUser.c_str():NULL, 
                m_strPassword.size()?m_strPassword.c_str():NULL, 
                m_strDBname.size()?m_strDBname.c_str():NULL,
                m_iPort, NULL, CLIENT_MULTI_STATEMENTS) ) 
    {
        ErrorMessage();
        Close();
        return false;
    }
    return true;
}

void MysqlObj::Close() 
{
    if ( m_pMysql ) 
    {
        mysql_close(m_pMysql);
        m_pMysql = NULL;
    }
}

int MysqlObj::SelectDB(const char *pDatabase) 
{
    assert(m_pMysql);
    int iRet = mysql_select_db(m_pMysql, pDatabase);
    if (0 != iRet) 
    {
        ErrorMessage();
    }
    return iRet;
}

int MysqlObj::ExecuteSql(IN const char *pSql, OUT QueryResult& vecResult) 
{
    assert(m_pMysql);
    unsigned int iSqlSize = (unsigned int)strlen(pSql);

    if ( 0 != mysql_real_query(m_pMysql, pSql, iSqlSize) ) 
    {
        ErrorMessage();
        return -1;
    }
    unsigned iFieldCount = 0;
    unsigned iRowCount = 0;

    if ( 0 == (iFieldCount = mysql_field_count(m_pMysql)) ) 
    {
        // 当前结果集无数据,说明不是SELECT的Sql
        m_iAffectedRows = mysql_affected_rows(m_pMysql);
        m_iInsertId = mysql_insert_id(m_pMysql);
    }   
    else    
    {
        // Select的结果集
        MYSQL_RES *pRes = mysql_store_result(m_pMysql);
        if ( NULL == pRes ) 
        {
            ErrorMessage();
            return -1;
        }

        // 获取行数
        iRowCount = mysql_num_rows(pRes);
        m_iAffectedRows = iRowCount;
        // 当前为Select,修正insert_id为0
        m_iInsertId = 0;
        MYSQL_ROW pRow = NULL;
        for ( unsigned i = 0;i < iRowCount;i++ ) 
        {
            pRow = mysql_fetch_row(pRes);
            if ( !pRow ) 
            {
                ErrorMessage();
                mysql_free_result(pRes);
                return -1;
            }
            unsigned long *pLens = mysql_fetch_lengths(pRes); 
            if ( NULL == pLens ) 
            {
                ErrorMessage();
                mysql_free_result(pRes);
                return -1;
            }

            //构造一行
            vector<string> vecRow;
            for ( unsigned j = 0;j < iFieldCount;j++ ) 
            {
                vecRow.push_back(string(pRow[j], pLens[j]));
            }
            vecResult.addRow(vecRow);
        }
        // 释放当前结果集
        mysql_free_result(pRes);
    }

    // XXX:只保留第一个结果集,后续的忽略
    while(!mysql_next_result(m_pMysql)) 
    {
        if (0 == mysql_field_count(m_pMysql)) 
        {
            continue;
        }
        MYSQL_RES *pRes = mysql_store_result(m_pMysql);
        if ( NULL == pRes ) 
        {
            ErrorMessage();
            return -1;
        }
        // 释放当前结果集
        mysql_free_result(pRes);
    }

    return 0;
}

unsigned long long MysqlObj::AffectedRows() const
{
    return m_iAffectedRows;
}

unsigned long long MysqlObj::InsertId() const 
{
    return m_iInsertId;
}

MYSQL* MysqlObj::get() const
{
    return m_pMysql;
}

bool MysqlObj::Ping() const
{
    if(m_pMysql != NULL && !mysql_ping(m_pMysql))
        return true;
    else
        return false;
}
©️2020 CSDN 皮肤主题: 大白 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值