zl程序教程

您现在的位置是:首页 >  后端

当前栏目

C++搭建集群聊天室(九):数据库代码及用户模型代码封装

C++数据库封装集群代码 搭建 用户 模型
2023-09-14 09:15:27 时间

请添加图片描述

数据库模块

db.hpp

首先,在 include/server 目录下新增文件夹 db,用于存放数据库相关文件。
在 db 文件夹下新增文件:db.hpp

#ifndef DB_H_
#define DB_H_

#include<string>
#include<mysql/mysql.h>
#include<muduo/base/Logging.h>

using namespace std;

// 数据库配置信息 
static string server = "127.0.0.1"; 
static string user = "root"; 
static string password = "123456"; 
static string dbname = "chat"; 

// 数据库操作类 
class MySQL {

public: 
    // 初始化数据库连接 
    MySQL();
    
    // 释放数据库连接资源
    ~MySQL();

    // 连接数据库 
    bool connect();
    
    // 更新操作 
    bool update(string sql);
    
    // 查询操作 
    MYSQL_RES* query(string sql);
    
    //获取连接
    MYSQL* getconnection();

private: 
    MYSQL *_conn; 
};

#endif

接下来,实现这些函数

db.cpp

同样,在 src/server 目录下新建 db 文件夹,用于存放数据库文件。

新建 db.cpp

#include "db.hpp"

MySQL::MySQL() { _conn = mysql_init(nullptr); }

// 释放数据库连接资源
MySQL::~MySQL()
{
    if (_conn != nullptr)
        mysql_close(_conn);
}

// 连接数据库
bool MySQL::connect()
{
    MYSQL *p = mysql_real_connect(_conn, server.c_str(), user.c_str(), password.c_str(), dbname.c_str(), 3306, nullptr, 0);
    if (p != nullptr)
    {
        mysql_query(_conn, "set names gbk");
    }
    return p;
}

// 更新操作
bool MySQL::update(string sql)
{
    if (mysql_query(_conn, sql.c_str()))
    {
        LOG_INFO << __FILE__ << ":" << __LINE__ << ":" << sql << "更新失败!";
        return false;
    }

    return true;
}

// 查询操作
MYSQL_RES * MySQL::query(string sql)
{
    if (mysql_query(_conn, sql.c_str()))
    {
        LOG_INFO << __FILE__ << ":" << __LINE__ << ":" << sql << "查询失败!";
        return nullptr;
    }

    return mysql_use_result(_conn);
}

MYSQL* MySQL::getconnection(){
    return _conn;
}

用户通用模块

user.hpp

封装数据。并提供数据的访问。

#ifndef USER_H_
#define USER_H_


#include<string>
using namespace std;

//User表的映射类
class User{
private:
    int id;
    string name;
    string password;
    string state;

public:
    User(int id = -1,string name = "",string pwd = "",string state = "offline"){
        this->id = id;
        this->name = name;
        this->password = pwd;
        this->state = state;
    }

    void setID(int id){
        this->id = id;
    }

    void setname(string name){
        this->name = name;
    }

    void setpassword(string password){
        this->password = password;
    }

    void setstate(string state){
        this->state = state;
    }

    int getID(){
        return this->id;
    }

    string getname(){
         return this->name;
    }

    string getpassword(){
        return this->password;
    }

    string getstate(){
        return this->state;
    }
};

#endif

东西不多,直接写这里。


usermodel.hpp

如果说,上面那个文件是 从数据库到用户层的映射,那么这组文件就是 业务层对用户业务的操作

#ifndef USERMODEL_H_
#define USERMODEL_H_

#include "user.hpp"

//User表的操作类
class UserModel{
public:
    bool insert(User &user);
    User query(int id);
    bool updateState(User user);
private:

};

#endif

usermodel.cpp

#include "usermodel.hpp"
#include "db.hpp"
#include<iostream>

using namespace std;

bool UserModel::insert(User &user){
    char sql[128] = {0};

    sprintf("insert into User(name,password,state) values('%s','%s','%s')",
        user.getname().c_str(),user.getpassword().c_str(),user.getstate().c_str());

    MySQL mysql;
    if(mysql.connect()){
        if(mysql.update(sql)){
            user.setID(mysql_insert_id(mysql.getconnection()));
            return true;
        }
    }
    return false;
}

// 根据用户号码查询用户信息
User UserModel::query(int id)
{
    // 1.组装sql语句
    char sql[1024] = {0};
    sprintf(sql, "select * from User where id = %d", id);

    MySQL mysql;
    if (mysql.connect())
    {
        MYSQL_RES *res = mysql.query(sql);
        if (res != nullptr)
        {
            MYSQL_ROW row = mysql_fetch_row(res);
            if (row != nullptr)
            {
                User user;
                user.setID(atoi(row[0]));
                user.setname(row[1]);
                user.setpassword(row[2]);
                user.setstate(row[3]);
                mysql_free_result(res);
                return user;
            }
        }
    }

    return User();
}

bool UserModel::updateState(User user){
    char sql[128] = {0};

    sprintf("updata User set state = '%s' where id = '%d'",user.getstate().c_str(),user.getID());

    MySQL mysql;
    if(mysql.connect()){
        if(mysql.update(sql)){
            return true;
        }
    }
    return false;
}

cmake 文件修改

最外层的 cmake 文件需要适当的做出调整。

加上下面这条

include_directories(${PROJECT_SOURCE_DIR}/include/server/db)

server 里面的 cmake 也要适当的做调整:

# 定义一个SRC_LIST变量,存放该目录下所有的源文件
aux_source_directory(. SRC_LIST)
aux_source_directory(./db SRC_LIST)

# 指定生成可执行文件
add_executable(ChatServer ${SRC_LIST})

# 指定可执行文件生成时需要链接的外部库
target_link_libraries(ChatServer muduo_net muduo_base pthread mysqlclient)

加一个源文件的路径,加一个外库。


编译遇到问题请直接转文档 问题解决 专栏,这次的问题很难找到适配的资料,需要靠经验嘿嘿。