From cec6937344e179a6db50c6386b24afcff165561f Mon Sep 17 00:00:00 2001
From: zyf <2786722087@qq.com>
Date: 星期三, 02 四月 2025 09:21:04 +0800
Subject: [PATCH] zyf_0402_log

---
 Server/张怡帆/code/ConnectMysql.cpp |  300 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 300 insertions(+), 0 deletions(-)

diff --git "a/Server/\345\274\240\346\200\241\345\270\206/code/ConnectMysql.cpp" "b/Server/\345\274\240\346\200\241\345\270\206/code/ConnectMysql.cpp"
new file mode 100644
index 0000000..16f292a
--- /dev/null
+++ "b/Server/\345\274\240\346\200\241\345\270\206/code/ConnectMysql.cpp"
@@ -0,0 +1,300 @@
+#include "ConnectMysql.h"
+
+// 构造函数实现,初始化成员变量
+ConnectMysql::ConnectMysql()
+{
+	m_result = nullptr;
+	m_mysqlRow = nullptr;
+
+	m_conn = mysql_init(nullptr);	// 初始化MySQL连接对象,传入nullptr会自动分配一个MYSQL对象
+	if (m_conn == nullptr)
+	{
+		cout << "初始化失败" << endl;
+		return;
+	}
+	cout << "初始化成功" << endl;
+}
+
+// 析构函数实现,释放结果集和数据库连接资源
+ConnectMysql::~ConnectMysql()
+{
+	freeRes();// 释放结果集
+	if (m_conn != nullptr) {
+		mysql_close(m_conn);
+		m_conn = nullptr;
+		cout << "数据库连接关闭" << endl;
+	}
+}
+
+// 释放结果集资源的函数实现
+void ConnectMysql::freeRes()
+{
+	if (m_result) {
+		mysql_free_result(m_result);
+		m_result = nullptr;
+	}
+}
+
+// 使用 Shell 脚本备份数据库
+void ConnectMysql::backupCurrentDBUsingShell(const string path)
+{
+	string user = "root";
+	string passwd = "1";
+	string dbName = "AI_datas";
+	string command = "sh backup_script.sh " + user + " " + passwd + " " + dbName + " " + path;
+	int result = system(command.c_str());
+	if (result != 0) {
+		cerr << "备份失败!" << endl;//cerr: 这是一个标准输出流,用于输出错误信息.
+	}
+}
+
+// 连接数据库的函数实现
+bool ConnectMysql::connect(const string user, const string passwd,
+	const string dbName, string ip, const unsigned short port)
+{
+
+	MYSQL* res = mysql_real_connect(m_conn, ip.c_str(), user.c_str(),
+		passwd.c_str(), dbName.c_str(), port, nullptr, 0);	// 使用mysql_real_connect连接数据库
+
+	if (res == nullptr)
+	{
+		cout << "数据库连接失败" << endl;
+		return false;
+	}
+	cout << "数据库连接成功" << endl;
+
+	if (mysql_set_character_set(m_conn, "GBK")) {// 设置字符集,防止乱码
+		puts("字符集设置错误!");
+	}
+	else {
+		puts("字符集设置成功!");
+	}
+
+	return res != nullptr;
+}
+
+// 执行更新操作(增删改)的函数实现
+bool ConnectMysql::update(const string sql) const
+{
+	// 执行SQL语句,成功返回0,失败返回非0值
+	int res = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned int>(sql.size()));
+	if (res != 0) {
+		return false;
+	}
+	return true;
+}
+
+// 执行查询操作的函数实现
+bool ConnectMysql::query(const string sql)
+{
+	freeRes();// 释放结果集
+
+	int res = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned int>(sql.size()));	// 执行查询SQL语句
+	if (res != 0) {
+		cout << "查询失败" << endl;
+		return false;
+	}
+	// 获取查询结果集
+	m_result = mysql_store_result(m_conn);
+	if (m_result == nullptr) {
+		cout << "查询失败" << endl;
+		return false;
+	}
+	return true;
+}
+
+// 遍历查询结果集的函数实现
+bool ConnectMysql::getRes()
+{
+	if (m_result != nullptr) {
+		// 获取结果集中的下一行数据
+		m_mysqlRow = mysql_fetch_row(m_result);
+		if (m_mysqlRow != nullptr) {
+			return true;
+		}
+		freeRes();
+	}
+	return false;
+}
+
+// 获取结果集中指定字段值的函数实现
+string ConnectMysql::getValue(const int fieldIndex) const//fieldIndex:字段索引
+{
+	// 获取结果集中的字段数量
+	int fieldCount = mysql_num_fields(m_result);
+	if (fieldIndex >= fieldCount || fieldIndex < 0) {
+		return string();// 返回空字符串
+	}
+	// 获取指定字段的值
+	char* value = m_mysqlRow[fieldIndex];
+
+	// 获取各字段值的长度数组
+	unsigned long* len = mysql_fetch_lengths(m_result);// mysql_fetch_lengths:获取所有字段值的长度
+	unsigned long length = len[fieldIndex];
+	// 防止数据中存在\0导致数据丢失,使用指定长度构造字符串
+	return string(value, length);
+}
+
+// 获取查询结果集的函数实现
+vector<vector<string>> ConnectMysql::getQueryResults()
+{
+	vector<vector<string>> results;
+	if (m_result != nullptr)
+	{
+		int num_fields = mysql_num_fields(m_result);
+		while ((m_mysqlRow = mysql_fetch_row(m_result)))
+		{
+			vector<string> row;//vector<string> 代表一行查询结果
+			for (int i = 0; i < num_fields; ++i)
+			{
+				if (m_mysqlRow[i] != nullptr)
+				{
+					row.push_back(m_mysqlRow[i]);
+				}
+				else
+				{
+					row.push_back("");  // 处理 NULL 值
+				}
+			}
+			results.push_back(row);
+		}
+	}
+	return results;
+}
+
+//// 切换数据库的函数实现
+//bool ConnectMysql::selectDB(const string dbName) const
+//{
+//	// 执行切换数据库的操作
+//	int res = mysql_select_db(m_conn, dbName.c_str());
+//	if (res != 0) {
+//		return false;
+//	}
+//	return true;
+//}
+
+//// 创建数据库的函数实现
+//bool ConnectMysql::createDB(const string dbName) const
+//{
+//	// 拼接创建数据库的SQL语句
+//	string sql = "create database " + dbName + ";";
+//	// 执行创建数据库的SQL语句
+//	int res = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned long>(sql.size()));
+//	if (res != 0) {
+//		return false;
+//	}
+//	return true;
+//}
+
+// 备份当前数据库的函数实现
+void ConnectMysql::backupCurrentDB(const string path)
+{
+	// 查询当前数据库中的所有表
+	string sql = "show tables";
+	int r = mysql_real_query(m_conn, sql.c_str(), static_cast<unsigned long>(sql.size()));
+	if (r != 0) {
+		return;
+	}
+	// 获取查询结果集
+	MYSQL_RES* tableRes = mysql_store_result(m_conn);
+	for (int i = 0; i < mysql_num_rows(tableRes); ++i) {
+		// 获取表名
+		MYSQL_ROW tableName = mysql_fetch_row(tableRes);
+		// 备份每个表
+		backupCurrentTable(path, tableName[0]);
+	}
+}
+
+// 备份当前表的函数实现
+void ConnectMysql::backupCurrentTable(const string path, const string tableName)
+{
+	// 拼接备份表的文件名
+	string file = path + tableName + ".sql";
+	// 打开文件用于写入
+	ofstream ofs(file);
+	if (!ofs.is_open()) {
+		cout << "文件打开失败!" << endl;
+		return;
+	}
+	// 写入表结构
+	string showCreate = "show create table " + tableName + ";";//show create table: 查看表结构
+	bool res = query(showCreate);
+	if (!res) {
+		return;
+	}
+	if (getRes()) {
+		string writeSQL = getValue(1) + ";\n";
+		ofs.write(writeSQL.c_str(), writeSQL.size());
+	}
+	// 写入表数据
+	string sql = "select * from " + tableName + ";";
+	res = query(sql);
+	if (!res) {
+		return;
+	}
+	while (getRes()) {
+		string writeSQL = "insert into `" + tableName + "` values(";
+		for (int i = 0; !getValue(i).empty(); ++i) {
+			if (i != 0) {
+				writeSQL += ",";
+			}
+			// 获取字段类型
+			MYSQL_FIELD* valueType = mysql_fetch_field_direct(m_result, i);//获取当前列的字段信息。根据字段类型判断是否需要加引号
+			if (valueType->type == MYSQL_TYPE_DECIMAL
+				|| valueType->type == MYSQL_TYPE_TINY
+				|| valueType->type == MYSQL_TYPE_SHORT
+				|| valueType->type == MYSQL_TYPE_LONG
+				|| valueType->type == MYSQL_TYPE_FLOAT
+				|| valueType->type == MYSQL_TYPE_DOUBLE
+				|| valueType->type == MYSQL_TYPE_TIMESTAMP
+				|| valueType->type == MYSQL_TYPE_LONGLONG
+				|| valueType->type == MYSQL_TYPE_INT24
+				|| valueType->type == MYSQL_TYPE_BOOL) {//小数,整数,浮点数,时间,长整数,短整数,布尔值
+				writeSQL += getValue(i);
+			}
+			else {
+				writeSQL += "'" + getValue(i) + "'";
+			}
+		}
+		writeSQL += ");\n";
+		ofs.write(writeSQL.c_str(), writeSQL.size());
+	}
+	ofs.close();
+}
+
+// 开启事务的函数实现
+bool ConnectMysql::transaction() const
+{
+	// 将事务提交设置为手动提交,开启事务
+	return mysql_autocommit(m_conn, false);
+}
+
+// 提交事务的函数实现
+bool ConnectMysql::commit() const
+{
+	// 提交事务
+	return mysql_commit(m_conn);
+}
+
+// 回滚事务的函数实现
+bool ConnectMysql::rollback() const
+{
+	// 回滚事务
+	return mysql_rollback(m_conn);
+}
+
+// 刷新连接存活起始时间点的函数实现
+void ConnectMysql::refreashAliveTime()
+{
+	// 更新连接存活起始时间点
+	m_alivetime = std::chrono::steady_clock::now();// 获取当前时间点
+}
+
+// 获取连接存活时长的函数实现
+ll ConnectMysql::getAliveTime()
+{
+	// 计算连接存活时长,转换为毫秒  
+	auto now = std::chrono::steady_clock::now();
+	std::chrono::duration<long long, std::milli> res = std::chrono::duration_cast<std::chrono::milliseconds>(now - m_alivetime);
+	return res.count();
+}
\ No newline at end of file

--
Gitblit v1.8.0