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

news2024/11/15 15:15:05

文章目录

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

一、数据管理模块实现

(一)功能

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

二、设计

(一)数据库设计

创建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;
          }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1121791.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3ds Max2023安装教程(最新最详细)

目录 一.简介 二.安装步骤 软件&#xff1a;3ds Max版本&#xff1a;2023语言&#xff1a;简体中文大小&#xff1a;6.85G安装环境&#xff1a;Win11/Win10/Win8/Win7硬件要求&#xff1a;CPU3GHz 内存16G(或更高&#xff09;下载通道①百度网盘丨64位下载链接&#xff1a; …

【蓝桥每日一题]-动态规划 (保姆级教程 篇10)#方格取数

高能预警&#xff1a;讲了这么久动态规划了&#xff0c;该上点有难度的题吧 目录 题目&#xff1a;方格取数 思路&#xff08;解法一&#xff09;&#xff1a; 解法二&#xff1a; 题目&#xff1a;方格取数 思路&#xff08;解法一&#xff09;&#xff1a; 如果只有两个方向…

openCV Cuda

下载 git clone https://github.com/opencv/opencv.git git clone https://github.com/opencv/opencv_contrib.git确保准备好以下内容 1&#xff1a; visual studio &#xff08;不是vs code&#xff09; 2&#xff1a;下载后的两个包裹会放在以下结构 这样放的原因是我Ub…

Java EE-使用Servlet搭建一个简单的前后端交互程序

上述前端和后端的代码如下&#xff1a; 前端&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"vie…

数据库笔记——SQL语言DQL语句

schema等于database 数据库 datagrip中使用控制台进行操作&#xff1a; 右键new QueryConsole 创建表格create table中&#xff1a; 1. 括号内不管是定义属性还是声明约束&#xff0c;都使用逗号分隔&#xff0c;最后一句不用逗号 2. 括号外使用分号 DDL&#xff1a;数据库定…

python接口自动化测试(单元测试方法)

一、环境搭建 python unittest requests实现http请求的接口自动化Python的优势&#xff1a;语法简洁优美, 功能强大, 标准库跟第三方库灰常强大&#xff0c;建议大家事先了解一下Python的基础;unittest是python的标准测试库&#xff0c;相比于其他测试框架是python目前使用最广…

思辨:移动开发的未来在哪?

前段时间在知乎看到关于移动开发未来的问题&#xff0c;就尝试回答了一下&#xff0c;也触发了我对移动开发未来的思考。 移动开发未来怎么样? - 知乎 https://www.zhihu.com/question/613842211 什么是移动开发&#xff1f; 我们口中说的移动开发是什么&#xff0c;从广义和…

项目管理实战总结(二)-沟通路径

在一个大型的项目管理中&#xff0c;不同的沟通路径&#xff0c;会对整个事情的进展形成不同的影响。从项目管理的视角来看&#xff0c;该如何驱动项目有效进展&#xff0c;失之毫厘谬以千里。 沟通路径&#xff1a;调查问卷的推动事宜 在项目进行到了后期&#xff0c;甲方希…

项目管理实战总结(一)

前言 主动申请参与到这个项目&#xff0c;是非常清楚工作强度大、难度大的情况的&#xff0c;明知山有虎偏向虎山行。我确信通过这个项目&#xff0c;一定有我需要的东西。目前项目已经完成了终验的专家评审&#xff0c;进入到运维阶段。对于个人而言&#xff0c;如果记忆中只…

全网超细,自动化测试-数据管理/实施落地问题,跟着直接上高速...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 自动化测试——测…

C++迭代器失效

在STL中&#xff0c;有些操作会导致迭代器失效&#xff0c;即之前获取的迭代器无法再安全地使用。这是因为这些操作可能会改变容器的结构&#xff0c;例如插入、删除元素等。 具体来说&#xff0c;以下情况下迭代器会失效&#xff1a; 1. 当插入或删除元素导致容器中的内存重新…

Go并发可视化解释 - sync.WaitGroup

场景 Avito是一名校车司机&#xff0c;他帮助4个Gopher孩子上学。每天&#xff0c;Avito在他们的社区等待孩子们。他不知道孩子们需要多长时间&#xff0c;但他确切地知道有4个孩子他需要等待。 1*aZnEggopv4Tsbyyj3e5JFg.png 当一个孩子准备好时&#xff0c;他/她会说&#xf…

跨境干货 | 如何搭建自己的独立站?

很多跨境电商在第三方平台经营许久后&#xff0c;会想摆脱第三方规则的限制建立起自己的品牌。 对于新手来说建立独立站是很有挑战的&#xff0c;建立独立站前首先我们需要了解一下什么是独立站&#xff1f;从字面意思来理解就是拥有属于自己的网站自己搭建跨境独立站&#xff…

【Python语言速回顾】——基础语法

目录 引入 一、PEP8代码规范和风格 二、变量和数据 1、变量 2、运算符 三、三种程序结构 1、分支结构 2、循环结构 四、组合数据类型 1、列表&#xff08;list&#xff09; 2、元组&#xff08;tuple&#xff09; 3、字典&#xff08;dict&#xff09; 5、集合&…

Python学习基础笔记七十七——json序列化

客户端和服务端之间需要交换数据才能完成各种功能。 假设 服务端程序都是用Python语言开发的话&#xff0c;那么 服务端从数据库中获取的最近的交易列表&#xff0c;可能就是像下面这样的一个Python列表对象&#xff1a; historyTransactions [{time : 20170101070311, #…

LoadRunner录制脚本+编写脚本

LoadRunner安装* 为什么选择LoadRunner 1&#xff09;Jmeter没有录制功能 2&#xff09;可以设计非常非常丰富的测试场景 3&#xff09;LoadRunner能够产出非常丰富的测试报告 LoadRunner三大组件的关系 每个组件是干什么的 VUG&#xff1a;录制脚本&#xff0c;&#xff…

天梯赛:L1-005 考试座位号

每个 PAT 考生在参加考试时都会被分配两个座位号&#xff0c;一个是试机座位&#xff0c;一个是考试座位。正常情况下&#xff0c;考生在入场时先得到试机座位号码&#xff0c;入座进入试机状态后&#xff0c;系统会显示该考生的考试座位号码&#xff0c;考试时考生需要换到考试…

线程是如何进行创建的

对于任何一个进程来讲&#xff0c;即便我们没有主动去创建线程&#xff0c;进程也是默认有一个主线程的。线程是负责执行二进制指令的&#xff0c;它会根据项目执行计划书&#xff0c;一行一行执行下去。进程要比线程管的宽多了&#xff0c;除了执行指令之外&#xff0c;内存、…

局域网下多台windows电脑时间同步

windows时间同步 最近在项目中遇见了多台windows电脑的时间同步问题。在这个项目中&#xff0c;有五台电脑&#xff0c;五台电脑处于同一局域网下&#xff0c;其中有一台可以连接互联网&#xff08;A电脑&#xff09;。我需要将其他四台电脑&#xff08;B、C、D、E电脑&#xf…

在Word中,图片显示不全

在今天交作业的时候&#xff0c;发现了一个非常SB的事情&#xff0c;把图片复制过去显示不完全&#xff1a; 使用文心一言查看搜索了一下&#xff0c;发现可能是以下几种原因&#xff1a; 图片所在行的行高设置不正确。可以重新设置行高&#xff0c;具体步骤包括打开图片显示…