From 2e420a0a40cc3fcc62bcb42ee6a25f4ad4f22dd3 Mon Sep 17 00:00:00 2001
From: wangky <m1561510467@163.com>
Date: 星期三, 06 十一月 2024 16:26:04 +0800
Subject: [PATCH] 1

---
 Server/王琨元/code/ConnectionPool.cpp |  182 +++++++++++--------------
 Server/王琨元/code/MysqlConn.h        |   41 +++--
 Server/王琨元/code/MysqlConn.cpp      |  133 +++++++++++++------
 Server/王琨元/code/ConnectionPool.h   |   58 +++----
 4 files changed, 219 insertions(+), 195 deletions(-)

diff --git "a/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.cpp" "b/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.cpp"
index ce7acb2..2fff64c 100644
--- "a/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.cpp"
+++ "b/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.cpp"
@@ -1,125 +1,101 @@
 #include "stdafx.h"
 #include "ConnectionPool.h"
 
-#include <fstream>
-#include <iostream>
-#include <thread>
-
-ConnectionPool* ConnectionPool::getInstance() {
-	static ConnectionPool connPool;
-	return &connPool;
-}
 
 ConnectionPool::ConnectionPool() {
-	// 加载配置文件
-	if (!parseJsonFile()) {
-		std::cout << "parseJsonFile is failed!" << std::endl;
-		return;
-	}
-	for ( int i = 0 ; i < m_min_conn ; i++ ) {
-		addConnection( );
-	}
-	// 创建一个线程,对连接数进行监控 ,连接数不足就再继续创建
-	std::thread producer(&ConnectionPool::produce, this);
-	// 对连接数进行监控 ,如果有太多空闲得线程 ,那么就对其进行销毁
-	std::thread recycler( &ConnectionPool::recycle,  this);
 
-	// 线程分离
-	producer.detach();
-	recycler.detach();
+
+    m_min_conn = 5; // 假设最小连接数为 5
+    m_max_conn = 10; // 假设最大连接数为 10
+    m_timeout = 1000; // 假设连接超时时间为 1000 毫秒
+    max_del_time = 60000; // 假设最大空闲时间为 60000 毫秒
+
+    for (int i = 0; i < m_min_conn; i++) {
+        addConnection();
+    }
+    // 创建一个线程,对连接数进行监控 ,连接数不足就再继续创建
+    thread producer(&ConnectionPool::produce, this);
+    // 对连接数进行监控 ,如果有太多空闲得线程 ,那么就对其进行销毁
+    thread recycler(&ConnectionPool::recycle, this);
+
+    // 线程分离
+    producer.detach();
+    recycler.detach();
 }
 
-bool ConnectionPool::parseJsonFile() {
-
-	/*std::ifstream ifs("dbconf.json");
-	Reader rd;
-	Value root;
-	rd.parse(ifs, root);
-	if ( root.isObject( ) ) {
-		m_ip = root["ip"].asString();
-		m_port = root["port"].asInt();
-		m_userName = root["userName"].asString();
-		m_passwd = root["password"].asString();
-		m_db = root["dbName"].asString();
-		m_min_conn = root["minSize"].asInt();
-		m_max_conn = root["maxSize"].asInt();
-		max_del_time = root["maxDleTime"].asInt();
-		m_timeout = root["timeout"].asInt();
-		return true;
-	}*/
-	return false;
-}
-
-void ConnectionPool::description() {
-	std::cout << m_ip << ". " << m_userName << ". " << m_passwd << ". " << m_db << ". "
-		       << m_port << ". " << m_max_conn << ". " << m_min_conn << ". " << m_timeout << ". " 
-		       << max_del_time << std::endl;
-}
 
 ConnectionPool::~ConnectionPool() {
-	while (!m_connkQueue.empty()) {
-		MysqlConn* conn = m_connkQueue.front();
-		m_connkQueue.pop();
-		delete  conn;
-	}
-
+    while (!m_connkQueue.empty()) {
+        MysqlConn* conn = m_connkQueue.front();
+        m_connkQueue.pop();
+        delete conn;
+    }
 }
 
 void ConnectionPool::addConnection() {
-	MysqlConn* conn = new MysqlConn();
-	if ( !conn->connect( m_ip, m_userName, m_passwd, m_db, m_port  ) ) {
-		std::cout << "ConnectionPool connect to mysql is failed!" << std::endl;
-		delete conn;
-		return;
-	}
-	conn->refreshActiveTime( );
-	m_connkQueue.push(conn);
-	m_cond.notify_one();   // 唤醒一个线程
+    MysqlConn* conn = new MysqlConn();
+    if (!conn->isConnected()) {
+        cout << "ConnectionPool connect to mysql is failed!" << endl;
+        delete conn;
+        return;
+    }
+    conn->refreshActiveTime();
+    m_connkQueue.push(conn);
+    m_cond.notify_one();   // 唤醒一个线程
 }
 
-void ConnectionPool::produce(){
-	while (true) {
-		std::unique_lock<std::mutex> lock(m_mutex);
-		while (m_connkQueue.size() >= m_min_conn) { // 连接队列的数量大于最小的连接数
-			m_cond.wait(lock);
-		}
-		addConnection();
-	}
+void ConnectionPool::produce() {
+    while (true) {
+        unique_lock<mutex> lock(m_mutex);
+        while (m_connkQueue.size() >= m_min_conn) { // 连接队列的数量大于最小的连接数
+            m_cond.wait(lock);
+        }
+        addConnection();
+    }
 }
 
 // 删除空闲连接
 void ConnectionPool::recycle() {
-	while ( true ) {
-		std::this_thread::sleep_for( std::chrono::milliseconds(500));   // 休眠500 ms
-		std::unique_lock<std::mutex>lock(m_mutex);
-		while ( m_connkQueue.size() > m_min_conn ) {
-			MysqlConn* conn = m_connkQueue.front( );
-			if (conn->getActiveTime() >= max_del_time) {
-				m_connkQueue.pop();
-				delete conn;
-			}
-			else {
-				break;
-			}
-		}
-	}
+    while (true) {
+        this_thread::sleep_for(chrono::milliseconds(500));   // 休眠 500 ms
+        unique_lock<mutex> lock(m_mutex);
+        while (m_connkQueue.size() > m_min_conn) {
+            MysqlConn* conn = m_connkQueue.front();
+            if (conn->getActiveTime() >= max_del_time) {
+                m_connkQueue.pop();
+                delete conn;
+            }
+            else {
+                break;
+            }
+        }
+    }
 }
 
-std::shared_ptr<MysqlConn>  ConnectionPool::getMysqlConn() {
-	
-	std::unique_lock<std::mutex>lock(m_mutex);
-	while ( m_connkQueue.empty()) {
-		// 如果等待一段时间后,队列还是为空,返回一个 null
-		if ( std::cv_status::timeout == m_cond.wait_for(lock, std::chrono::milliseconds(m_timeout)) ) {
-			if( m_connkQueue.empty( ) )    return nullptr;
-		}
-	}
-	std::shared_ptr<MysqlConn> connPtr(std::move(m_connkQueue.front()), [this](MysqlConn* conn) {
-		std::unique_lock <std::mutex>lock(m_mutex) ;
-		conn->refreshActiveTime();
-		m_connkQueue.push(conn);
-		});
-	m_connkQueue.pop();
-	m_cond.notify_one();   // 唤醒阻塞的生产者线程,开始生产
-	return connPtr;
+shared_ptr<MysqlConn> ConnectionPool::getMysqlConn() {
+    unique_lock<mutex> lock(m_mutex);
+    while (m_connkQueue.empty()) {
+        // 如果等待一段时间后,队列还是为空,返回一个 null
+        if (cv_status::timeout == m_cond.wait_for(lock, chrono::milliseconds(m_timeout))) {
+            if (m_connkQueue.empty()) return nullptr;
+        }
+    }
+    shared_ptr<MysqlConn> connPtr(move(m_connkQueue.front()), [this](MysqlConn* conn) {
+        unique_lock<mutex> lock(m_mutex);
+        conn->refreshActiveTime();
+        m_connkQueue.push(conn);
+        });
+    m_connkQueue.pop();
+    m_cond.notify_one();   // 唤醒阻塞的生产者线程,开始生产
+    return connPtr;
+}
+void ConnectionPool::description() {
+    cout << m_ip << ". " << m_userName << ". " << m_passwd << ". " << m_db << ". "
+        << m_port << ". " << m_max_conn << ". " << m_min_conn << ". " << m_timeout << ". "
+        << max_del_time << endl;
+}
+
+ConnectionPool* ConnectionPool::getInstance() {
+    static ConnectionPool connPool;
+    return &connPool;
 }
\ No newline at end of file
diff --git "a/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.h" "b/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.h"
index bce6a07..c78a46e 100644
--- "a/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.h"
+++ "b/Server/\347\216\213\347\220\250\345\205\203/code/ConnectionPool.h"
@@ -1,50 +1,44 @@
 #pragma once
 
-#include <queue>
-#include <mutex>
-#include <condition_variable>
-//#include <json/json.h>
-
 #include "MysqlConn.h"
-
-//using namespace Json;
 
 class ConnectionPool
 {
 public:
-	static ConnectionPool* getInstance( );
+    static ConnectionPool* getInstance();
 
-	std::shared_ptr<MysqlConn>  getMysqlConn();    // 从数据库连接池获取连接
+    shared_ptr<MysqlConn> getMysqlConn();    // 从数据库连接池获取连接
 
-	ConnectionPool(const ConnectionPool& other) = delete;
-	ConnectionPool& operator = (const ConnectionPool & other ) = delete;
-	
-	~ConnectionPool();
+    ConnectionPool(const ConnectionPool& other) = delete;
+    ConnectionPool& operator=(const ConnectionPool& other) = delete;
 
-	void description();
+    ~ConnectionPool();
+
+    void description();
 
 protected:
-	ConnectionPool( );   // 构造函数
+    ConnectionPool();   // 构造函数
 private:
-	bool parseJsonFile();   // 解析配置
+    // 不再需要解析配置文件的函数
+    // bool parseJsonFile();   // 解析配置
 
-	void produce();
-	void recycle();
-	void addConnection();  // 增加连接数
+    void produce();
+    void recycle();
+    void addConnection();  // 增加连接数
 
-	std::string  m_ip;
-	std::string  m_userName;
-	std::string  m_passwd;
-	std::string  m_db;
-	unsigned short m_port;
+    // 写死的数据库连接参数
+    string m_ip = "127.0.0.1";
+    string m_userName = "root";
+    string m_passwd = "123456";
+    string m_db = "mayi_kunlun";
+    unsigned short m_port = 3306;
 
-	int m_max_conn;
-	int m_min_conn;
+    int m_max_conn;
+    int m_min_conn;
 
-	int m_timeout;      // 连接超时时间
-	int max_del_time;   // 最大删除时间( 连接空闲时间超过这个,就给当前连接关闭 )
-	std::queue<MysqlConn*>m_connkQueue ;   // 连接队列
-	std::mutex m_mutex;  // 互斥锁
-	std::condition_variable m_cond;   // 条件变量
+    int m_timeout;      // 连接超时时间
+    int max_del_time;   // 最大删除时间( 连接空闲时间超过这个,就给当前连接关闭 )
+    queue<MysqlConn*> m_connkQueue;   // 连接队列
+    mutex m_mutex;  // 互斥锁
+    condition_variable m_cond;   // 条件变量
 };
-
diff --git "a/Server/\347\216\213\347\220\250\345\205\203/code/MysqlConn.cpp" "b/Server/\347\216\213\347\220\250\345\205\203/code/MysqlConn.cpp"
index 5725af8..071cf5f 100644
--- "a/Server/\347\216\213\347\220\250\345\205\203/code/MysqlConn.cpp"
+++ "b/Server/\347\216\213\347\220\250\345\205\203/code/MysqlConn.cpp"
@@ -1,37 +1,60 @@
 #include "stdafx.h"
 #include "MysqlConn.h"
-#include <regex>
+
 
 
 // 初始化连接
+// 初始化连接
 MysqlConn::MysqlConn() {
-    mysql_ = mysql_init(mysql_);
-    // 设置字符集
-    if (mysql_) mysql_set_character_set(mysql_, "gbk");
-}
-
-// 连接数据库
-bool MysqlConn::connect(std::string ip, std::string userName, std::string passwd, std::string db, int port) {
-    mysql_ = mysql_real_connect(mysql_, ip.c_str(), userName.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0);
-    if (!mysql_) {
-        return false;
+    m_mysql = mysql_init(nullptr);
+    if (!m_mysql) {
+        cout << "Failed to initialize MySQL." << endl;
+        return;
     }
-    return true;
+    // 设置字符集
+    if (m_mysql) mysql_set_character_set(m_mysql, "gbk");
+    // 使用写死的参数连接数据库
+    m_mysql = mysql_real_connect(m_mysql, "127.0.0.1", "root", "123456", "mayi_kunlun", 3306, nullptr, 0);
+    if (!m_mysql) {
+        cout << "MysqlConn connect to mysql is failed!" << endl;
+        // 确保在连接失败时正确清理资源
+        mysql_close(m_mysql);
+        m_mysql = nullptr;
+    }
+    // 初始化 row_ 和 res_
+    m_row = nullptr;
+    m_res = nullptr;
 }
+bool MysqlConn::isConnected() {
+    return m_mysql != nullptr;
+}
+// 连接数据库
+//bool MysqlConn::connect() {
+//    string ip = "127.0.0.1";
+//    string userName = "root";
+//    string passwd = "123456";
+//    string db = "mayi_kunlun";
+//    int port = 3306;
+//    m_mysql = mysql_real_connect(mysql_, ip.c_str(), userName.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0);
+//    if (!m_mysql) {
+//        return false;
+//    }
+//    return true;
+//}
 
 // 释放资源
 MysqlConn::~MysqlConn() {
-    if (mysql_) {
-        mysql_close(mysql_);
-        mysql_ = nullptr;
+    if (m_mysql) {
+        mysql_close(m_mysql);
+        m_mysql = nullptr;
     }
     freeRes();
 }
 
 // 更新数据
-bool MysqlConn::update(std::string sql) {
+bool MysqlConn::update(string sql) {
     // 参数化查询优化后的安全检查
-    MYSQL_STMT* stmt = mysql_stmt_init(mysql_);
+    MYSQL_STMT* stmt = mysql_stmt_init(m_mysql);
     if (!stmt) {
         return false;
     }
@@ -53,11 +76,36 @@
     return true;
 }
 
+bool MysqlConn::query(string sql, vector<vector<string>>& result)
+{
+    freeRes();
+    int ret = mysql_query(m_mysql, sql.c_str());
+    if (ret != 0) {
+        fprintf(stderr, "Query failed: %s\n", mysql_error(m_mysql));
+        return false;
+    }
+    // 获取查询结果
+    m_res = mysql_store_result(m_mysql);
+    if (!m_res)   return false;
+    //将结果集转到二维数组result里面
+    //int col_cnt = m_mysql->field_count;
+    int col_cnt = mysql_field_count(m_mysql);
+    cout << col_cnt << endl;
+    while (m_row = mysql_fetch_row(m_res)) {
+        vector<string> tmp;
+        for (int i = 0; i < col_cnt; i++) {
+            tmp.push_back(m_row[i]);
+        }
+        result.push_back(tmp);
+    }
+    return true;
+}
+
 // 查询数据库
-bool MysqlConn::query(std::string sql) {
+bool MysqlConn::query(string sql) {
     freeRes();
     // 参数化查询优化后的安全检查
-    MYSQL_STMT* stmt = mysql_stmt_init(mysql_);
+    MYSQL_STMT* stmt = mysql_stmt_init(m_mysql);
     if (!stmt) {
         return false;
     }
@@ -75,8 +123,8 @@
         mysql_stmt_close(stmt);
         return false;
     }
-    res_ = mysql_stmt_result_metadata(stmt);
-    if (!res_) {
+    m_res = mysql_stmt_result_metadata(stmt);
+    if (!m_row) {
         mysql_stmt_close(stmt);
         return false;
     }
@@ -86,59 +134,60 @@
 
 // 得到结果集
 bool MysqlConn::getResult() {
-    if (res_) {
-        row_ = mysql_fetch_row(res_);
-        if (row_) return true;
+    if (m_row) {
+        m_row = mysql_fetch_row(m_res);
+        if (m_row) return true;
     }
     return false;
 }
 
 // 获取结果集的字段
-std::string MysqlConn::getField(int index) {
-    int cols = mysql_num_fields(res_);
-    if (index >= cols || index < 0) return std::string("");
+string MysqlConn::getField(int index) {
+    int cols = mysql_num_fields(m_res);
+    if (!m_res || index >= cols || index < 0) return string("");
 
-    char* value = row_[index];
-    unsigned long len = mysql_fetch_lengths(res_)[index];
-    return std::string(value, len);
+    char* value = m_row[index];
+    // 使用显式类型转换
+    unsigned long len = static_cast<unsigned long>(mysql_fetch_lengths(m_res)[index]);
+    return string(value, len);
 }
 
 // 事务操作
 bool MysqlConn::transaction() {
-    return mysql_autocommit(mysql_, false);
+    return mysql_autocommit(m_mysql, false);
 }
 
 // 提交事务
 bool MysqlConn::commit() {
-    return mysql_commit(mysql_);
+    return mysql_commit(m_mysql);
 }
 
 // 事务回滚
 bool MysqlConn::rollback() {
-    return mysql_rollback(mysql_);
+    return mysql_rollback(m_mysql);
 }
 
 void MysqlConn::refreshActiveTime() {
-    activeTime_ = std::chrono::steady_clock::now();
+    m_activeTime = chrono::steady_clock::now();
 }
 
 long long MysqlConn::getActiveTime() {
     // 纳米
-    std::chrono::nanoseconds nased = std::chrono::steady_clock::now() - activeTime_;
+    chrono::nanoseconds nased = chrono::steady_clock::now() - m_activeTime;
     // 转换成毫米
-    std::chrono::microseconds millsed = std::chrono::duration_cast<std::chrono::microseconds>(nased);
+    chrono::microseconds millsed = chrono::duration_cast<chrono::microseconds>(nased);
     return millsed.count();   // 多少毫秒
 }
 
 // 安全校验实现,这里简单使用正则表达式判断是否包含危险字符
-bool MysqlConn::isSqlSafe(const std::string& sql) {
-    std::regex dangerousPattern(".*(['\";\\-+=]).*");
-    return!std::regex_search(sql, dangerousPattern);
+bool MysqlConn::isSqlSafe(const string& sql) {
+    regex dangerousPattern(".*(['\";\\-+=]).*");
+    return!regex_search(sql, dangerousPattern);
 }
 
 void MysqlConn::freeRes() {
-    if (res_) {
-        mysql_free_result(res_);
-        res_ = nullptr;
+    if (m_res) {
+        mysql_free_result(m_res);
+        m_res = nullptr;
     }
 }
\ No newline at end of file
diff --git "a/Server/\347\216\213\347\220\250\345\205\203/code/MysqlConn.h" "b/Server/\347\216\213\347\220\250\345\205\203/code/MysqlConn.h"
index 00c9917..a6506d1 100644
--- "a/Server/\347\216\213\347\220\250\345\205\203/code/MysqlConn.h"
+++ "b/Server/\347\216\213\347\220\250\345\205\203/code/MysqlConn.h"
@@ -2,48 +2,53 @@
 
 #include <string>
 #include <WinSock2.h>
-//#include <mysql.h>
 #include "MySQL/include/mysql.h"
 #include <string.h>
 #include <chrono>
-
+#include <iostream>
+#include <memory>
+#include <queue>
+#include <mutex>
+#include <condition_variable>
+#include <regex>
 #pragma comment(lib,"./MySQL/lib/libmysql.lib")
 
+using namespace std;
 class MysqlConn
 {
 public:
 	// 初始化连接
 	MysqlConn();
 	// 连接数据库
-	bool connect(std::string ip, std::string userName, std::string passwd, std::string db , int port = 3306);
+	//bool connect();
 	// 释放资源
-	~MysqlConn( );
+	~MysqlConn();
 	// 更新数据库  ( insert  update delete )
-	bool update(std::string sql);
+	bool update(string sql);
 	// 查询数据库
-	bool query(std::string sql);
+	bool query(string sql, vector<vector<string>>& result);
+	bool query(string sql);
 	// 得到结果集
 	bool getResult();
 	// 获取结果集的字段
-	std::string getField(int index);
+	string getField(int index);
 	// 事务操作
 	bool transaction();
 	// 提交事务
-	bool commit( );
+	bool commit();
 	// 事务回滚
 	bool rollback();
 
-	void refreshActiveTime( );   // 刷新活跃时间
+
+	void refreshActiveTime();   // 刷新活跃时间
 	long long getActiveTime();   // 获取当前活跃的时间间隔 
 	// 安全校验接口
-	bool isSqlSafe(const std::string& sql);
-
-private:
-
+	bool isSqlSafe(const string& sql);
+	bool isConnected();
+protected:
 	void freeRes();
-	MYSQL* mysql_ = NULL ;
-	MYSQL_RES* res_ = NULL;
-	MYSQL_ROW row_ = nullptr;
-	std::chrono::steady_clock::time_point  activeTime_;
+	MYSQL* m_mysql;
+	MYSQL_RES* m_res;
+	MYSQL_ROW m_row;
+	chrono::steady_clock::time_point  m_activeTime;
 };
-

--
Gitblit v1.8.0