| #ifndef MYSQLCONNECTION_H |
| #define MYSQLCONNECTION_H |
| #include <iostream> |
| #include <mysql.h> |
| #include <vector> |
| |
| class MySQLConnection |
| { |
| public: |
| |
| |
| |
| MySQLConnection(); |
| MySQLConnection(MySQLConnection& another) = delete; |
| MySQLConnection& operator=(MySQLConnection& another) = delete; |
| MySQLConnection(MySQLConnection&& another); |
| MySQLConnection& operator=(MySQLConnection&& another); |
| |
| ~MySQLConnection(); |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| bool connect(std::string host, std::string user, std::string pwd, std::string dbName, unsigned int port = 3306); |
| |
| bool disconnect(); |
| |
| |
| |
| |
| |
| bool update(std::string sqlUpdate); |
| |
| |
| |
| |
| |
| bool query(std::string sqlQuery); |
| |
| |
| |
| |
| std::vector<std::string> fields(); |
| |
| |
| |
| |
| bool next(); |
| |
| |
| |
| |
| |
| std::string value(unsigned int index); |
| |
| |
| |
| |
| |
| std::string value(std::string fieldName); |
| |
| |
| |
| |
| bool startTransaction(); |
| |
| |
| |
| |
| bool commit(); |
| |
| |
| |
| |
| bool rollback(); |
| private: |
| |
| |
| |
| void freeQueryResult(); |
| |
| MYSQL* mysqlConn = nullptr; |
| MYSQL_RES* queryResult = nullptr; |
| std::vector<std::string> fieldNames; |
| MYSQL_ROW queryResultRow = nullptr; |
| }; |
| |
| #endif |
| #include "MySQLConnection.h" |
| |
| MySQLConnection::MySQLConnection() |
| { |
| mysqlConn = mysql_init(mysqlConn); |
| } |
| |
| MySQLConnection::MySQLConnection(MySQLConntion&& another) |
| { |
| this->mysqlConn=another.mysqlConn; |
| this->queryResult=another.mysqlConn; |
| another->mysqlConn=nullptr; |
| another->mysqlConn=nullptr; |
| } |
| |
| MySQLConnection& MySQLConnection::operator=(MySQLConntion&& another) |
| { |
| if(this->mysqlConn!=another.mysqlConn) |
| { |
| if(this->mysqlConn!=nullptr) |
| { |
| delete this->mysqlConn; |
| this->mysqlConn=another.mysqlConn; |
| another.mysqlConn=nullptr; |
| } |
| if(this->queryResult!=nullptr) |
| { |
| mysql_free_result(this->queryResult); |
| this->queryResult=another.queryResult; |
| this->fieldNames.swap(another.fieldNames); |
| } |
| } |
| return *this; |
| } |
| |
| MySQLConnection::~MySQLConnection() |
| { |
| if (mysqlConn != nullptr) |
| { |
| mysql_close(mysqlConn); |
| freeQueryResult(); |
| } |
| } |
| |
| bool MySQLConnection::connect(std::string host, std::string user, std::string pwd, std::string dbName, unsigned int port) |
| { |
| mysqlConn = mysql_real_connect(mysqlConn, host.c_str(), user.c_str(), pwd.c_str(), dbName.c_str(), |
| port, nullptr, 0); |
| return mysqlConn != nullptr; |
| } |
| |
| bool MySQLConnection::disconnect() |
| { |
| if (mysqlConn != nullptr) |
| { |
| mysql_close(mysqlConn); |
| freeQueryResult(); |
| } |
| } |
| |
| bool MySQLConnection::update(std::string sqlUpdate) |
| { |
| return mysql_query(mysqlConn, sqlUpdate.c_str()) == 0; |
| } |
| |
| bool MySQLConnection::query(std::string sqlQuery) |
| { |
| if (mysql_query(mysqlConn, sqlQuery.c_str()) != 0) |
| { |
| return false; |
| } |
| |
| freeQueryResult(); |
| queryResult = mysql_store_result(mysqlConn); |
| return true; |
| } |
| |
| std::vector<std::string> MySQLConnection::fields() |
| { |
| if (queryResult == nullptr) |
| { |
| return fieldNames; |
| } |
| |
| std::vector<std::string>(0).swap(fieldNames); |
| int colCount = mysql_num_fields(queryResult); |
| MYSQL_FIELD* fields = mysql_fetch_fields(queryResult); |
| |
| for (int i = 0; i < colCount; i++) |
| { |
| fieldNames.emplace_back(fields[i].name); |
| } |
| return fieldNames; |
| } |
| |
| bool MySQLConnection::next() |
| { |
| if (queryResult == nullptr) |
| { |
| return false; |
| } |
| |
| queryResultRow = mysql_fetch_row(queryResult); |
| return queryResultRow != nullptr; |
| } |
| |
| std::string MySQLConnection::value(unsigned int index) |
| { |
| if (queryResult == nullptr || queryResultRow == nullptr) |
| { |
| return std::string(); |
| } |
| |
| if (index < 0 || index >= mysql_num_fields(queryResult)) |
| { |
| return std::string(); |
| } |
| |
| |
| |
| |
| |
| unsigned long* colRealLengths = mysql_fetch_lengths(queryResult); |
| return std::string(queryResultRow[index], colRealLengths[index]); |
| } |
| |
| std::string MySQLConnection::value(std::string fieldName) |
| { |
| if (queryResult == nullptr || queryResultRow == nullptr) |
| { |
| return std::string(); |
| } |
| |
| if (fieldName == "") |
| { |
| return std::string(); |
| } |
| |
| for (unsigned int i = 0; i < fieldNames.size(); i++) |
| { |
| if (fieldName == fieldNames[i]) |
| { |
| return value(i); |
| } |
| } |
| return std::string(); |
| } |
| |
| void MySQLConnection::freeQueryResult() |
| { |
| if (queryResult != nullptr) |
| { |
| mysql_free_result(queryResult); |
| std::vector<std::string>(0).swap(fieldNames); |
| } |
| } |
| |
| bool MySQLConnection::startTransaction() |
| { |
| return mysql_autocommit(mysqlConn, 0) == 0; |
| } |
| |
| bool MySQLConnection::commit() |
| { |
| return mysql_commit(mysqlConn) == 0; |
| } |
| |
| bool MySQLConnection::rollback() |
| { |
| return mysql_rollback(mysqlConn) == 0; |
| } |
| #ifndef MYSQLCONNPOOL_H |
| #define MYSQLCONNPOOL_H |
| #include "MySQLConntion.h" |
| #include<pthread.h> |
| #include<assert.h> |
| #include<vector> |
| |
| class MysqlConnPool |
| { |
| private: |
| int m_minSize; |
| int m_maxSize; |
| int m_size; |
| int m_countLocked; |
| vector<MySQLConntion> m_conns; |
| vector<pthread_mutex_t> m_mutexs; |
| pthread_t pthManage; |
| |
| private: |
| void manage(void* arg) |
| { |
| while(true) |
| { |
| if(m_countLocked>0.8*m_size && 1.2*m_size<=m_maxSize) |
| { |
| |
| int i=m_size; |
| m_size=1.2*m_size; |
| for(;i<m_size;++i) |
| { |
| MySQLConntion con; |
| m_conns.push_back(con); |
| pthread_mutex_t mtx; |
| m_mutexs.push_back(mtx); |
| } |
| } |
| else if(m_countLocked<0.4*m_size && 0.8*m_size>=m_minSize && 0.8*m_size<=m_maxSize) |
| { |
| |
| int icount=m_size; |
| m_size=static_cast<int>(0.8*m_size); |
| icount-=m_size; |
| for(auto iter1=m_conns.begin(),iter2=m_mutexs.begin();iter1!=m_conns.end()&&iter2!=m_mutexs.end();) |
| { |
| if(pthread_mutex_trylock(&(*iter2))==0) |
| { |
| iter1=m_conns.erase(iter1); |
| iter2=m_mutexs.erase(iter2); |
| --icount; |
| if(icount==0) break; |
| } |
| else |
| { |
| iter1++; |
| iter2++; |
| } |
| } |
| } |
| |
| sleep(5); |
| } |
| } |
| |
| public: |
| MysqlConnPool(int minSize, int maxSize, int size):m_minSize(minSize),m_maxSize(maxSize),m_size(size) |
| { |
| assert(size>=m_minSize&&size<=m_maxSize); |
| m_countLocked=0; |
| for(int i=0;i<m_size;++i) |
| { |
| MySQLConntion con; |
| m_conns.push_back(con); |
| } |
| for(int i=0;i<m_size;++i) |
| { |
| pthread_mutex_t mtx; |
| m_mutexs.push_back(mtx); |
| } |
| |
| pthread_create(&pthManage,NULL,manage,NULL); |
| } |
| |
| ~MysqlConnPoll() |
| { |
| freeconns(); |
| pthread_join(&pthManage,NULL); |
| } |
| |
| |
| bool initconns() |
| { |
| |
| for (int ii=0;ii<m_size;ii++) |
| { |
| if(!m_conns[ii].connect("127.0.0.1","root","root","dbtest")) |
| return false; |
| } |
| |
| for(int i=0;i<m_size;i++) |
| { |
| if(pthread_mutex_init(&m_mutexs[i],NULL)!=0) |
| return false; |
| } |
| |
| return true; |
| } |
| |
| MySQLConnection* getconn() |
| { |
| |
| for(int i=0;i<m_size;i++) |
| { |
| if(pthread_mutex_trylock(&m_mutexs[i])==0) |
| { |
| m_countLocked++; |
| return &m_conns[i]; |
| } |
| } |
| |
| return NULL; |
| } |
| |
| void freeconn(MySQLConnection* in_conn) |
| { |
| if(in_conn!=NULL) |
| { |
| for(int i=0;i<m_size;i++) |
| { |
| if(in_conn==&m_conns[i]) |
| { |
| pthread_mutex_unlock(&m_mutexs[i]); |
| m_countLocked--; |
| } |
| } |
| } |
| } |
| |
| void freeconns() |
| { |
| for(int i=0;i<m_size;i++) |
| { |
| pthread_mutex_destroy(&m_mutexs[i]); |
| m_conns[i].disconnect(); |
| } |
| m_conns.clear(); |
| m_mutexs.clear(); |
| m_countLocked=0; |
| } |
| }; |
| |
| #endif |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)