用户注册业务代码和测试

70 阅读2分钟

数据库的操作和业务代码分离开,在业务层只能看到对象,看不到数据库的操作。我们要定义一些相关的ORM类,和数据库的表一一对应的,才能把数据库读出来的字段合成一个对象提供给业务层使用

我们在inlcude/server下创建一个文件夹:model
首先我们在inlcude/server/model文件夹下创建文件:user.hpp

#ifndef USER_H
#define USER_H

#include <string>
using namespace std;

class User
{
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 setPwd(string pwd) { this->password = pwd; }
    void setState(string state) { this->state = state; }

    int getId() { return this->id; }
    string getName() { return this->name; }
    string getPwd() { return this->password; }
    string getState() { return this->state; }

private:
    int id;
    string name;
    string password;
    string state;
};

#endif

我们在inlcude/server/model文件夹下再创建文件:usermodel.hpp
UserModel是User表的数据操作类,和业务不相关,针对表的CRUD

#ifndef USERMODEL_H
#define USERMODEL_H

#include "user.hpp"

//User表的数据操作类,和业务不相关,针对表的CRUD
class UserModel
{
public:
    //User表的增加方法
    bool insert(User &user);
};

#endif

在src/server下创建一个文件夹:model
在src/server/model下创建文件:usermodel.cpp

#include "usermodel.hpp"
#include "db.h"

#include <iostream>
using namespace std;

bool UserModel::insert(User &user)
{
    // 1. 组装sql语句
    char sql[1024] = {0};
    // 此处刚注册,还没有登录,肯定是offline,我们在User类的构造函数里state默认为offline
    sprintf(sql, "insert into user(name, password, state) values('%s', '%s', '%s')",
            user.getName().c_str(), user.getPwd().c_str(), user.getState().c_str());
    MySQL mysql;

    if (mysql.connect()) // 2. 连接数据库
    {
        if (mysql.update(sql)) // 3. 发送sql语句插入数据
        {
            //获取插入成功的用户数据生成的主键id
            user.setId(mysql_insert_id(mysql.getConnection()));
            return true;
        }
    }
    return false;
}

完善include/public.hpp

#ifndef PUBLIC_H
#define PUBLIC_H

//server和client的公共文件
enum EnMsgType
{
    LOGIN_MSG = 1, //登录消息
    REG_MSG, //注册消息
    REG_MSG_ACK //注册响应消息
};

#endif

完善include/server/chatservice.hpp

image.png

完善src/server/chatservice.cpp中的reg方法

#include "chatservice.hpp"
#include "public.hpp"

#include <muduo/base/Logging.h>
#include<string>
using namespace std;
using namespace muduo;

//获取单例对象的接口函数
ChatService* ChatService:: instance()
{
    static ChatService service;
    return &service;
}

//注册消息以及对应的回调操作
ChatService :: ChatService()
{
    _msgHandlerMap.insert({LOGIN_MSG, bind(&ChatService::login, this,_1,_2,_3)});
    _msgHandlerMap.insert({REG_MSG, bind(&ChatService::reg,this,_1,_2,_3)});
}

 //获取消息对应的处理器
MsgHandler ChatService::getHandler(int msgid)
{
    //记录错误日志,msgid没有对应的事件处理回调
    auto it = _msgHandlerMap.find(msgid);
    if(it == _msgHandlerMap.end()){
        //返回一个默认的处理器,空操作
        return [=](const TcpConnectionPtr &conn, json &js, Timestamp){
            LOG_ERROR << "msgid:"<<msgid<<" can not find handler!";
        };     
    }
    else{
         return _msgHandlerMap[msgid];
    }
}

//处理登录业务
void ChatService :: login(const TcpConnectionPtr &conn, json &js, Timestamp)
{
    LOG_INFO<<"do login service!!!";
}
//处理注册业务
void ChatService :: reg(const TcpConnectionPtr &conn, json &js, Timestamp)
{
    string name = js["name"];
    string pwd = js["password"];

    User user;
    user.setName(name);
    user.setPwd(pwd);
    bool state = _userModel.insert(user);

    if(state)
    {
        //注册成功
        json responce;
        responce["msgid"] = REG_MSG_ACK;
        //errno=0响应成功,不为0那肯定还有errmsg说明错误消息
        responce["errno"] = 0;
        responce["id"] = user.getId();
        conn->send(responce.dump());
    }
    else{
        //注册失败
        json responce;
        responce["msgid"] = REG_MSG_ACK;
        responce["errno"] = 1;
        conn->send(responce.dump());
    }
}

在chat/CMakeLists.txt中加入model的头文件搜索路径

image.png 在src/server/CMakeLists.txt中加入model的源文件编译路径

image.png

编译并测试一下注册功能

image.png 检查数据库是否插入成功

image.png

若出现问题,可以打开查询日志开关:set global general_log = "on";
show global variables like 'general%';查看查询日志位置

image.png

查看查询日志

image.png