文章目录
一、数据管理模块实现
(一)功能
数据管理模块主要负责对于数据库中数据进行统一的增删改查管理,其他模块要对数据操作都必须通过数据管理模块完成。
二、设计
(一)数据库设计
创建user表, 用来表示用户信息及积分信息
- 用户信息, 用来实现登录、注册、游戏对战数据管理等功能
- 积分信息, 用来实现匹配功能
cpp
drop database if exists gobang;
create database if not exists gobang;
create table if not exists user(
id int primary key auto_increment,
username varchar(32) unique key not null,
password varchar(128) not null,
score int,
total_count int,
win_count int
);
(二)创建user_table类
数据库中有可能存在很多张表,每张表中管理的数据又有不同,要进⾏的数据操作也各不相同,因此我们可以为每⼀张表中的数据操作都设计⼀个类,通过类实例化的对象来访问这张数据库表中的数据,这样的话当我们要访问哪张表的时候,使用哪个类实例化的对象即可。
创建user_table类, 该类的作用是负责通过 MySQL 接口管理用户数据。主要提供了四个方法:
- select_by_name: 根据用户名查找用户信息, 用于实现登录功能
- insert: 新增用户,用户实现注册功能
- login: 登录验证,并获取完整的用户信息
- win: 用于给获胜玩家修改分数
- lose: 用户给失败玩家修改分数
cpp
// 2.数据管理模块的封装和实现
/*
实现一个我们自己的mysql客户端来访问服务器进行数据的操作!
针对我们管理的每一张表都设计一个类,通过类实例化的对象管理指定的数据库表!*/
class user_table {
private:
MYSQL *_mysql; //mysql操作句柄
std::mutex _mutex;//互斥锁保护数据库的访问操作
public:
user_table() {
const std::string &username,
const std::string &password,
const std::string &dbname,
uint16_t port = 3306) {
_mysql = mysql_util::mysql_create(host, username, password, dbname, port);
assert(_mysql != NULL);
}
~user_table() {
mysql_util::mysql_destroy(_mysql);
_mysql = NULL;
}
// 注册时新增用户
bool insert(Json::Value &user) {
#define INSERT_USER "insert user values(null, '%s', password('%s'), 1000, 0, 0);"
if(user["password"].isNull() || user["username"].isNull()) {
DLOG("INPUT PASSWORD OR USERNAME");
return false;
}
char sql[4096] = {0};
sprintf(sql, INSERT_USER, user["username"].asCString(), user["password"].asCString());
bool ret = mysql_util::mysql_exec(_mysql, sql);
if (ret == false) {
DLOG("insert user info failed!!\n");
return false;
}
return true;
}
//登录验证,并返回详细的用户信息
bool login(Json::Value &user) {
if (user["password"].isNull() || user["username"].isNull()) {
DLOG("INPUT PASSWORD OR USERNAME");
return false;
}
//以用户名和密码共同作为查询过滤条件,查询到数据则表示用户名密码一致,没有信息则用户名密码错误
#define LOGIN_USER "select id, score, total_count, win_count from user where username='%s' and password=password('%s');"
char sql[4096];
sprintf(sql, LOGIN_USER, user["username"].asCString(), user["password"].asCString());
MYSQL_RES *res = NULL;
{
std::unique_lock<std::mutex> lock(_mutex);
bool ret = mysql_util::mysql_exec(_mysql, sql);
if (ret == false) {
DLOG("user login failed!!\n");
return false;
}
//按理说要么有数据,要么没有数据,就算有数据也只能有一条数据
res = mysql_store_result(_mysql);
if (res == NULL) {
DLOG("have no login user info!!");
return false;
}
}
int row_num = mysql_num_rows(res);
if (row_num != 1) {
DLOG("the user information queried is not unique!!");
return false;
}
MYSQL_ROW row = mysql_fetch_row(res);
user["id"] = (Json::UInt64)std::stol(row[0]);
user["score"] = (Json::UInt64)std::stol(row[1]);
user["total_count"] = std::stoi(row[2]);
user["win_count"] = std::stoi(row[3]);
mysql_free_result(res);
return true;
}
// 通过用户名获取用户信息
bool select_by_name(const std::string &name, Json::Value &user) {
#define USER_BY_NAME "select id,score,total_count,win_count from user where username='%s';"
char sql[4096] = {0};
sprintf(sql, USER_BY_NAME, name.c_str());
MYSQL_RES *res = NULL;
{
std::unique_lock<std::mutex> lock(_mutex);
bool ret = mysql_util::mysql_exec(_mysql,sql);
if (ret == false) {
DLOG("get user by name failed!!\n");
return false;
}
// 按理说要么有数据,要么没有数据,就算有数据也只能有一条数据
res = mysql_store_result(_mysql);
if (res == NULL) {
DLOG("have no user info!!");
return false;
}
}
int row_num = mysql_num_rows(res);
if (row_num != 1) {
DLOG("the user information queried is not unique!!");
return false;
}
MYSQL_ROW row = mysql_fetch_row(res);
user["id"] = (Json::UInt64)std::stoi(row[0]);
user["id"] = (Json::UInt64)std::stol(row[0]);
user["username"] = name;
user["score"] = (Json::UInt64)std::stol(row[1]);
user["total_count"] = std::stoi(row[2]);
user["win_count"] = std::stoi(row[3]);
mysql_free_result(res);
return true;
}
// 通过id获取用户信息
bool select_by_id(uint64_t id, Json::Value &user) {
#define USER_BY_ID "select username, score, total_count, win_count from user where id=%d;"
char sql[4096] = {0};
sprintf(sql, USER_BY_ID, id);
MYSQL_RES *res = NULL;
{
std::unique_lock<std::mutex> lock(_mutex);
bool ret = mysql_util::mysql_exec(_mysql, sql);
if (ret == false) {
DLOG("get user by id failed!!\n");
return false;
}
//按理说要么有数据,要么没有数据,就算有数据也只能有一条数据
res = mysql_store_result(_mysql);
if (res == NULL) {
DLOG("have no user info!!");
return false;
}
}
int row_num = mysql_num_rows(res);
if (row_num != 1) {
DLOG("the user information queried is not unique!!");
return false;
}
MYSQL_ROW row = mysql_fetch_row(res);
user["id"] = (Json::UInt64)id;
user["username"] = row[0];
user["score"] = (Json::UInt64)std::stol(row[1]);
user["total_count"] = std::stoi(row[2]);
user["win_count"] = std::stoi(row[3]);
mysql_free_result(res);
return true;
}
//胜利时天梯分数增加30分,战斗场次增加1,胜利场次增加1
bool win(uint64_t id) {
#define USER_WIN "update user set score=score+30, total_count=total_count+1, win_count=win_count+1 where id=%d;"
char sql[4096] = {0};
sprintf(sql, USER_WIN, id);
bool ret = mysql_util::mysql_exec(_mysql, sql);
if (ret == false) {
DLOG("update win user info failed!!\n");
return false;
}
return true;
}
//失败时天梯分数减少30,战斗场次增加1,其他不变
bool lose(uint64_t id) {
#define USER_LOSE "update user set score=score-30, total_count=total_count+1 where id=%d;"
char sql[4096] = {0};
sprintf(sql, USER_LOSE, id);
bool ret = mysql_util::mysql_exec(_mysql, sql);
if (ret == false) {
DLOG("update lose user info failed!!\n");
return false;
}
return true;
}
};