MySQL数据库交互类设计

1、类声明:
#pragma once
#include <mysql.h>
#include <stdlib.h>
#include <stdio.h>

// 与数据库交互的工具类
class DBUtil {
public:
    // 默认构造
    DBUtil();

    // 移动构造
    DBUtil(DBUtil&& rv) noexcept;

    // 移动赋值
    DBUtil& operator=(DBUtil&& rv) noexcept;

    // 析构函数
    ~DBUtil();

    // 连接数据库
    // 主机ip地址、用户名、密码、数据库名、端口
    // 成功返回0
    // 失败返回-1
    int Connect(const char* host, const char* user, const char* passwd, const char* dbName, int port = 3306);

    // 断开连接
    void Disconnect();

    // 执行SQL语句
    // 成功返回0
    // 失败返回-1
    int SQL(const char* sql);

    // 获取结果集中表头信息
    // 失败返回空指针
    // MYSQL_FIELD(字段信息结构体)eg:
    // char *name                   字段名
    // char *table                  所属表名
    // enum enum_field_tyoes type   类型
    // unsigned int length          子段宽度
    // unsigned int flags           约束/属性
    MYSQL_FIELD* Desc();

    // 获取结果集的列数
    size_t Cols();

    // 获取结果集的行数
    size_t Rows();

    // 返回上一次操作影响的条目数,针对DML语句
    size_t AffectItems();

    // 下一行查询结果
    // 空指针结束
    char** Next();

    // 打印结果集信息
    // 成功返回0
    // 失败返回-1
    int Print();

private:
    // 初始化函数,申请基本资源
    void Init();

protected:
    // 数据库操作句柄
    MYSQL* mql;
    // 查询的结果集
    MYSQL_RES* res;
};

2、类实现:
DBUtil::DBUtil() :mql(nullptr), res(nullptr) { }

DBUtil::DBUtil(DBUtil&& rv) noexcept :mql(rv.mql), res(rv.res) {
    rv.mql = nullptr;
    rv.res = nullptr;
}

DBUtil& DBUtil::operator=(DBUtil&& rv) noexcept {
    this->mql = rv.mql;
    this->res = rv.res;
    rv.mql = nullptr;
    rv.res = nullptr;
    return *this;
}

DBUtil::~DBUtil() {
    if (this->res) mysql_free_result(this->res);
    if (this->mql) mysql_close(this->mql);
}

void DBUtil::Init() {
    mql = new MYSQL;
}

int DBUtil::Connect(const char* host, const char* user, const char* passwd, const char* dbName, int port) {
    this->Init();
    // 初始化操作句柄
    // PS:如果传入一个空指针,将返回一个自动分配的操作句柄(不建议这么做,在析构时可能出现问题)
    mysql_init(this->mql);
    // 连接数据库函数
    // 成功返回操作句柄
    // 失败返回空指针
    // 后两个参数设置为空和0即可
    // 详细可参考:https://dev.mysql.com/doc/c-api/8.0/en/mysql-real-connect.html
    if (!mysql_real_connect(this->mql, host, user, passwd, dbName, port, nullptr, 0)) {
        // 检错函数
        printf("%s\n", mysql_error(this->mql));
        return -1;
    }
    // 执行sql语句
    // 失败返回非0
    // SET NAMES GBK:设置编码格式,否则cmd下中文乱码
    if (mysql_query(this->mql, "set names gbk")) {
        printf("%s\n", mysql_error(this->mql));
        return -1;
    }
    return 0;
}

// 断开连接
void DBUtil::Disconnect() {
    if (this->res) {
        mysql_free_result(this->res);
        this->res = nullptr;
    }
    if (this->mql) {
        mysql_close(this->mql);
        this->mql = nullptr;
    }
}

int DBUtil::SQL(const char* sql) {
    if (!this->mql) {
        puts("Not connect database");
        return -1;
    }
    if (mysql_query(this->mql, sql)) {
        printf("%s\n", mysql_error(this->mql));
        return -1;
    }

    // 释放之前结果集所占内存
    if (this->res) {
        mysql_free_result(this->res);
        this->res = nullptr;
    }

    // 获取结果集
    // 失败返回空指针
    this->res = mysql_store_result(this->mql);
    // 如果结果集为空,列数为零说明可能执行了DML语句
    // 如果结果集为空,列数不为零说出现异常(内存分配失败等)
    if (!res && mysql_field_count(this->mql)) {
        printf("%s\n", mysql_error(this->mql));
        return -1;
    }

    return 0;
}

MYSQL_FIELD* DBUtil::Desc() { return this->res ? mysql_fetch_fields(this->res) : nullptr; }

size_t DBUtil::Cols() { return this->res ? mysql_num_fields(this->res) : 0; }

size_t DBUtil::Rows() { return this->res ? mysql_num_rows(this->res) : 0; }

size_t DBUtil::AffectItems() { return mysql_affected_rows(this->mql); }

char** DBUtil::Next() { return this->res ? mysql_fetch_row(this->res) : nullptr; }

int DBUtil::Print() {
    if (!this->res) return puts("empty set"), -1;

    MYSQL_FIELD* fd = this->Desc();
    if (!fd) return printf("%s\n", mysql_error(this->mql)), -1;

    size_t col = this->Cols();
    for (size_t i = 0; i < col; i++) printf("%s ", fd[i].name);
    puts("");
    // 每行数据
    char** data;
    // 获取下一行信息
    while (data = this->Next()) {
        for (size_t i = 0; i < col; i++) printf("%s ", data[i]);
        puts("");
    }
    return 0;
}
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IN0vation

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值