Mysql-连接池

#pragma once

#include <deque>
#include <mutex>
#include <boost/thread/thread.hpp>  
#include <boost/thread/tss.hpp>
#include <boost/serialization/singleton.hpp>
#include <boost/shared_array.hpp>
#include <boost/asio.hpp>
#include <thread>
#include <queue>
#include <atomic>
#include <cppconn/driver.h>
#include <cppconn/prepared_statement.h>

#define    DB_CONN_COUNT    4
using namespace std;

typedef std::shared_ptr<sql::Connection> CMysqlConnectPtr;

#define mysqlMgr MysqlContrlMgr::get_mutable_instance()
class MysqlContrlMgr : public boost::serialization::singleton<MysqlContrlMgr>
{
public:
    MysqlContrlMgr();
    ~MysqlContrlMgr();

    void Init(const char* chIp, const char* chUser, const char* chDBName, 
        const char* chPwd, unsigned short uPort = 3306);
public:    
    CMysqlConnectPtr GetActiveConnPtr();
    void RecodeConnect(CMysqlConnectPtr);
protected:
    STSqlConnParam m_sqlParam;                    // 数据库连接信息结构
    CMyMutex m_cs;                                //
    std::queue<CMysqlConnectPtr> conQueue;        // 连接队列
public:
    //*************************************************************************
    // 函数名称: SyncExecSQL        
    // 返 回 值: bool                --执行成功返回true, 否则返回false
    // 参    数: FUNCCALL fun        --可以是回调函数,仿函数,lambda表达式 
    // 函数说明: 同步执行一个数据库操作,
    //*************************************************************************
    template<class FUNCCALL>
    bool SyncExecSQL(FUNCCALL fun)
    {
        bool bResult = false;

        CMysqlConnectPtr pWrapper = GetActiveConnPtr();
        if (!pWrapper)
        {
            gLog.LogText(LOG_ERROR,
                "%s:%d;\r\n%s.\r\n", __FILE__, __LINE__,
                "SyncExecSQL(FUNCCALL fun)");
            return bResult;
        }
        try
        {
            fun(pWrapper);
            bResult = true;
        }
        catch (const string& e)
        {
            gLog.LogText(LOG_ERROR,
                "%s:%d;\r\n%s.\r\n", __FILE__, __LINE__,
                "SyncExecSQL(FUNCCALL fun)");
        }
        catch (...)
        {
        }
        RecodeConnect(pWrapper);
        return true;
    }
};
#include "CMysqlMgr.h"
static sql::Driver *driver = get_driver_instance();

MysqlContrlMgr::MysqlContrlMgr()
{

}

MysqlContrlMgr::~MysqlContrlMgr()
{
    while (conQueue.size() != 0)
    {
        CMysqlConnectPtr con = std::move(conQueue.front());
        con->close();
    }
}

//------------------------------------------------------------------------
// 函数名称: Init
// 返 回 值: void
// 参    数:
//const char* chIp,        -- IP
//const char* chUser,    -- 用户名
//const char* chDBName,    -- 数据库名
//const char* chPwd,    -- 密码
//unsigned short uPort    -- 端口
// 说    明: 数据库连接 初始化
//------------------------------------------------------------------------
void MysqlContrlMgr::Init(const char* chIp, const char* chUser, const char* chDBName, const char* chPwd, unsigned short uPort)
{
    m_sqlParam.m_strIp = chIp;
    m_sqlParam.m_strUser = chUser;
    m_sqlParam.m_strDBName = chDBName;
    m_sqlParam.m_strPwd = chPwd;
    m_sqlParam.m_uPort = uPort;

    try
    {
        for (int i = 0; i < DB_CONN_COUNT * 10; ++i)
        {
            bool b_true = true;
            char strHonst[100] = { '\0' };
            snprintf(strHonst, sizeof(strHonst), "tcp://%s:%d", m_sqlParam.m_strIp.c_str(), m_sqlParam.m_uPort);
            sql::Connection *conn = driver->connect(strHonst, m_sqlParam.m_strUser.c_str(), m_sqlParam.m_strPwd.c_str());
            conn->setClientOption("OPT_CONNECT_TIMEOUT", &m_sqlParam.time_out);
            conn->setClientOption("OPT_RECONNECT", &b_true);
            conn->setClientOption("CLIENT_MULTI_RESULTS", &b_true);
            conn->setClientOption("OPT_CHARSET_NAME", "utf8");
            conn->setSchema(m_sqlParam.m_strDBName.c_str());

            std::shared_ptr<sql::Connection> sp(conn,
                [](sql::Connection *conn) {
                delete conn;
            });
            conQueue.push(std::move(sp));
        }
    }
    catch (sql::SQLException &e)
    {
        gLog.LogText(LOG_ERROR, "%s:%d", __FUNCTION__, e.getErrorCode());
        throw  "e.getErrorCode";
    }

    cout << "init Mysql Connect Pool success !" << endl;
}


//------------------------------------------------------------------------
// 函数名称: GetActiveConnPtr
// 返 回 值: void
// 参    数:
// 说    明: 获取一个活动的数据库连接
//------------------------------------------------------------------------
CMysqlConnectPtr MysqlContrlMgr::GetActiveConnPtr()
{
    MyLock(m_cs, CLockableObject::EXCLUSIVE_TYPE);
    if (conQueue.size() > 0)
    {
        CMysqlConnectPtr con = conQueue.front();
        conQueue.pop();
        return con;
    }
    return nullptr;
}

//------------------------------------------------------------------------
// 函数名称: RecodeConnect
// 返 回 值: void
// 参    数:
// 说    明: 回收一个数据库连接
//------------------------------------------------------------------------
void MysqlContrlMgr::RecodeConnect(CMysqlConnectPtr Ptr)
{
    MyLock(m_cs, CLockableObject::EXCLUSIVE_TYPE);;
    
    conQueue.push(std::move(Ptr));

    cout << "conQueue Size = " << conQueue.size() <<endl;
    gLog.LogText(LOG_ERROR, "conQueue Size = %d", conQueue.size());
}

猜你喜欢

转载自www.cnblogs.com/osbreak/p/9979448.html