2.2.C++项目:网络版五子棋对战之数据管理模块-数据库的设计

文章目录

一、数据管理模块实现

(一)功能

数据管理模块主要负责对于数据库中数据进行统一的增删改查管理,其他模块要对数据操作都必须通过数据管理模块完成。

二、设计

(一)数据库设计

创建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;
          }
};
相关推荐
捕鲸叉25 分钟前
创建线程时传递参数给线程
开发语言·c++·算法
A charmer29 分钟前
【C++】vector 类深度解析:探索动态数组的奥秘
开发语言·c++·算法
Peter_chq32 分钟前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
前端青山2 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
青花瓷2 小时前
C++__XCode工程中Debug版本库向Release版本库的切换
c++·xcode
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
音徽编程2 小时前
Rust异步运行时框架tokio保姆级教程
开发语言·网络·rust
观音山保我别报错2 小时前
C语言扫雷小游戏
c语言·开发语言·算法
小屁孩大帅-杨一凡3 小时前
java后端请求想接收多个对象入参的数据
java·开发语言