数据管理模块实现
- 1.数据库表的设计
- 2.数据管理模块的封装和实现
- 2.1 user_table() && ~user_table()
- 2.2 insert() 注册时新增用户
- 2.3 login() 登录验证,并返回详细的用户信息
- 2.4 通过用户名获取用户信息 && 通过用户id获取用户信息
- 2.5 win() && lose()
项目链接: 五子棋项目
1.数据库表的设计
在数据库表的成员变量中,除了id,用户名,密码之外,还有一些是是针对于游戏中的设计
- id
- username
- password
- score:分数
- total_count:总场数
- win_count:赢的场数
create database if not exists gobang;
use gobang;
create table if not exists user(
id int primary key auto_increment,
username varchar(32) not null,
password varchar(32) not null,
score int,
total_count int,
win_count int
);
2.数据管理模块的封装和实现
实现一个mysql客户端来访问服务器进行数据的操作,为了项目的可拓展性,针对管理的每一张表都去设计一个类,我们这里是针对用户的数据所以设计的就是user类
这里的函数实现要搭配着上一篇文章实现的使用工具类中的mysql_util这个类。
2.1 user_table() && ~user_table()
user_table的初始化就是mysql_create()要传入的参数也是mysql_create这个函数所需要的参数,析构函数就直接调用mysql_destroy即可。
2.2 insert() 注册时新增用户
这里就是简单的使用sql语句即可,要对用户和密码不全的情况进行判断
bool insert(Json::Value &user)
{
#define INSERT_USER "insert user values(null, '%s', '%s', 1000, 0, 0);"
//密码用户不全
if (user["password"].isNull() || user["username"].isNull())
{
DLOG("INPUT PASSWORD OR USERNAME");
return false;
}
char sql[4096] = {0};
// sprintf(void *buf, char *format, ...)
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;
}
2.3 login() 登录验证,并返回详细的用户信息
mysql链接共享,所以在多个线程同时执行sql语句时会导致竞争,所以需要加锁保护,这里有一个新的写法在加锁的地方用括号括起来,这样就变成了一个区间,区间结束之后锁会自动释放。
{
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;
}
}
2.4 通过用户名获取用户信息 && 通过用户id获取用户信息
这两个的函数几乎一模一样,就是在sql查询语句中的查询条件不同
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::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;
}
2.5 win() && lose()
这也类似,一个是加分一个是减分
- 胜利时天梯分数增加30分,战斗场次增加1,胜利场次增加1
- 失败时天梯分数减少30,战斗场次增加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=%ld;"
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;
}