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

文章目录

  • 一、数据管理模块实现
    • (一)功能
  • 二、设计
    • (一)数据库设计
    • (二)创建user_table类

一、数据管理模块实现

(一)功能

数据管理模块主要负责对于数据库中数据进行统一的增删改查管理,其他模块要对数据操作都必须通过数据管理模块完成。
2.2.C++项目:网络版五子棋对战之数据管理模块的设计_第1张图片

二、设计

(一)数据库设计

创建user表, 用来表示用户信息及积分信息

  • 用户信息, 用来实现登录、注册、游戏对战数据管理等功能
  • 积分信息, 用来实现匹配功能
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: 用户给失败玩家修改分数
// 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;
          }
};

你可能感兴趣的:(CodeCrafters,c++,开发语言)