#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()); }