C++封装对MySQL的基本操作

1.环境搭建

在这里,我将使用vscode来搭建MySQL的编程环境。

首先,下载MySQL,配置好系统环境变量并运行MySQL数据库。

接着,vscode扩展中搜索并下载MySQLMySQL Syntax插件。

安装完成后,在资源管理器的MySQL栏中点击+号,依次输入host名称、用户名、密码和端口号(最后一项可为空)来与数据库创建链接。

接下来,我们需要在c_cpp_properties.json的includePath中添加MySQL的include路径。

当我们通过命令行编译文件时,需要通过-L参数来指定MySQL的lib目录路径,通过-l参数来指定所要链接的库

g++ .\main.cpp -L "C:\Program Files\MySQL\MySQL Server 8.0\lib" -l libmysql -o main

当然,我们也可以在tasks.json的arg参数中进行相应的设置。

"args": [
	"-g",
	"${workspaceFolder}\\main.cpp",
	"-L",
	"C:\\Program Files\\MySQL\\MySQL Server 8.0\\lib",
	"-l",
	"libmysql",
	"-o",
	"${workspaceFolder}\\main.exe"
]

下面,我们就可以在我们的项目中包含mysql.h的头文件了。

然而,在实际操作的过程中,vscode居然会在运行阶段产生如下的错误:

Unable to start debugging. Unexpected GDB output from command “-exec-run”.

经过大量的尝试,我们只需要将lib目录中的.dll文件搬到项目目录下就可以正常运行了。

到这里,我们就完成了MySQL的环境搭建。


2.MySQL基本类型

2.1 数据定义语言(Data Definition Language)

主要用于对数据对象的创建,即在正式开发前对数据库及表的操作。

2.2 数据操作语言(Data Manipulation Language)

主要用于对数据的修改与查询,在开发过程中往往作为核心部分与其他编程语言进行交互。

2.3 数据控制语言(Data Control Language)

用于数据库的权限管理操作,一般由数据库的管理员来负责。


3.MySQL基本语句(部分)

3.1 数据库操作语句

显示所有数据库

SHOW DATABASES;

创建数据库

CREATE DATABASE 数据库名;

删除数据库

DROP DATABASE 数据库名;

使用数据库

use 数据库名;

显示当前数据库下的所有数据表

show tables;

3.2 表操作

创建表

CREATE TABLE 
    (IF NOT EXISTS) 表名(
        变量1 类型1 [约束],
        变量2 类型2 [约束],
        ...
        变量n 类型n [约束]
    );

查看表结构

DESCRIBE 表名;

删除表

DROP TABLE 表名;

3.3 数据操作

插入数据

INSERT INTO
    表名 (变量1,变量2,...,变量n) 
VALUES (值1,值2,...,值n);

删除数据

DELETE FROM 表名 WHERE [条件]

修改数据

UPDATE 表名
SET 变量1 = 值1, 变量2 = 值2, ..., 变量n = 值n
WHERE [条件]

查询数据

SELECT * FROM 表名 [WHERE 条件]

4.MySQL.h基本库函数

  • mysql_init : 初始化MYSQL对象

  • mysql_options : 对MYSQL对象进行特殊设置

  • mysql_real_connect : 将MYSQL对象连接到数据库

  • mysql_query : 执行mysql语句并查询执行结果(执行结果将被存储),若执行成功则返回零,否则返回非零

  • mysql_store_result : 获取上一次查询的执行结果,用MYSQL_RES对象接收

  • mysql_fetch_row : 获取执行结果中的一行数据(可视为数组)

  • mysql_free_result : 释放MYSQL_RES对象的空间

  • mysql_close : 关闭MYSQL对象


5.封装对数据库的增删改查操作

5.1 信息类的封装

为了方便模拟和测试,我们设计如下的信息类:

/*info.h*/
#ifndef INFO_H
#define INFO_H
#include <iostream>

class Info
{
    int id;
    std::string name;
    int price;
    std::string detail;

public:
    int get_id() const;
    std::string get_name() const;
    int get_price() const;
    std::string get_detail() const;

    Info(int, std::string, int, std::string);
};

#endif
/*info.cpp*/
#include"info.h"

int Info::get_id() const
{
    return id;
}

std::string Info::get_name() const
{
    return name;
}

int Info::get_price() const
{
    return price;
}

std::string Info::get_detail() const
{
    return detail;
}

Info::Info(int _id, std::string _name, int _price, std::string _detail)
    : id(_id), name(_name), price(_price), detail(_detail){}

5.2 数据访问对象的封装

对于DAO类,我们采用单例模式来进行封装来避免实例化多个对象。我们将DAO类的构造函数私有化,并创建一个静态DAO对象,通过调用特定的静态方法get_instance来获得对象,这样就实现了单例模式。

/*dao.h*/
#ifndef DAO_H
#define DAO_H
#include <winsock.h>
#include "C:\Program Files\MySQL\MySQL Server 8.0\include\mysql.h"
#include <iostream>
#include <vector>
#include "info.h"

class DAO
{
public:
    static DAO *get_instance();
    bool insert_info(Info &info);
    bool update_info(Info &info);
    bool delete_info(int &id);
    std::vector<Info> get_info(std::string condition) const;

private:
    const char *host = "127.0.0.1";// ip地址
    const char *user = "root";// 用户名
    const char *pw = "123456";// 密码
    const char *database_name = "sqldemo";// 数据库名
    const char *table_name = "information";// 所要查询的表名
    const int port = 3306;// 端口号

    MYSQL *con;
    static DAO *dao;

    bool connect();
    DAO();
    ~DAO();
};

#endif
/*dao.cpp*/
DAO *DAO::dao = new DAO();

DAO *DAO::get_instance()
{
    return dao;
}

5.3 实现对数据库的增删改

对于数据库的增删改,我们都可以直接通过mysql语句来实现,只要通过mysql_query判断语句是否执行成功即可。

/*dao.cpp*/
bool DAO::insert_info(Info &info)
{
    char sql[2048];
    sprintf(sql, "insert into %s (id,name,price,detail) values(%d,'%s',%d,'%s')", table_name, info.get_id(), info.get_name().c_str(), info.get_price(), info.get_detail().c_str());
    if (mysql_query(con, sql))
    {
        fprintf(stderr, "Failed to insert data : Error:%s\n", mysql_error(con));
        return false;
    }
    return true;
}

bool DAO::update_info(Info &info)
{
    char sql[2048];
    sprintf(sql, "update %s set name = '%s',price = %d,detail = '%s' where id = %d", table_name, info.get_name(), info.get_price(), info.get_detail(), info.get_id());
    if (mysql_query(con, sql))
    {
        fprintf(stderr, "Failed to update data : Error:%s\n", mysql_error(con));
        return false;
    }
    return true;
}

bool DAO::delete_info(int &id)
{
    char sql[2048];
    sprintf(sql, "delete from %s where id = %d", table_name, id);
    if (mysql_query(con, sql))
    {
        fprintf(stderr, "Failed to delete data : Error:%s\n", mysql_error(con));
        return false;
    }
    return true;
}

5.4 实现对数据库的查询

在这里,我们通过vector容器来返回所有查询到的对象,通过传入condition来补全mysql语句中的查询条件,从查询结果中逐行获取信息对象并存入容器中。

/*dao.cpp*/
std::vector<Info> DAO::get_info(std::string condition) const
{
    std::vector<Info> info_list;
    char sql[2048];
    sprintf(sql, "select * from %s%s", table_name, condition.c_str());
    if (mysql_query(con, sql))
    {
        fprintf(stderr, "Failed to select data : Error:%s\n", mysql_error(con));
        return {};
    }
    MYSQL_RES *res = mysql_store_result(con);
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(res)))
    {
        Info info(atoi(row[0]), row[1], atoi(row[2]), row[3]);
        info_list.push_back(info);
    }
    mysql_free_result(res);
    return info_list;
}

6.完整代码

/*info.h*/
#ifndef INFO_H
#define INFO_H
#include <iostream>

class Info
{
    int id;
    std::string name;
    int price;
    std::string detail;

public:
    int get_id() const;
    std::string get_name() const;
    int get_price() const;
    std::string get_detail() const;

    Info(int, std::string, int, std::string);
};

#endif
/*info.cpp*/
#include"info.h"

int Info::get_id() const
{
    return id;
}

std::string Info::get_name() const
{
    return name;
}

int Info::get_price() const
{
    return price;
}

std::string Info::get_detail() const
{
    return detail;
}

Info::Info(int _id, std::string _name, int _price, std::string _detail)
    : id(_id), name(_name), price(_price), detail(_detail){}
/*dao.h*/
#ifndef DAO_H
#define DAO_H
#include <winsock.h>
#include "C:\Program Files\MySQL\MySQL Server 8.0\include\mysql.h"
#include <iostream>
#include <vector>
#include "info.h"

class DAO
{
public:
    static DAO *get_instance();
    bool insert_info(Info &info);
    bool update_info(Info &info);
    bool delete_info(int &id);
    std::vector<Info> get_info(std::string condition) const;

private:
    const char *host = "127.0.0.1";// ip地址
    const char *user = "root";// 用户名
    const char *pw = "123456";// 密码
    const char *database_name = "sqldemo";// 数据库名
    const char *table_name = "information";// 所要查询的表名
    const int port = 3306;// 端口号

    MYSQL *con;
    static DAO *dao;

    bool connect();
    DAO();
    ~DAO();
};

#endif
/*dao.cpp*/
#include "dao.h"

DAO *DAO::dao = new DAO();

DAO *DAO::get_instance()
{
    return dao;
}

bool DAO::connect()
{
    if (!mysql_real_connect(con, host, user, pw, database_name, port, NULL, 0))
    {
        fprintf(stderr, "Failed to connect to database : Error:%s\n", mysql_error(con));
        return false;
    }
    return true;
}

bool DAO::insert_info(Info &info)
{
    char sql[2048];
    sprintf(sql, "insert into %s (id,name,price,detail) values(%d,'%s',%d,'%s')", table_name, info.get_id(), info.get_name().c_str(), info.get_price(), info.get_detail().c_str());
    if (mysql_query(con, sql))
    {
        fprintf(stderr, "Failed to insert data : Error:%s\n", mysql_error(con));
        return false;
    }
    return true;
}

bool DAO::update_info(Info &info)
{
    char sql[2048];
    sprintf(sql, "update %s set name = '%s',price = %d,detail = '%s' where id = %d", table_name, info.get_name(), info.get_price(), info.get_detail(), info.get_id());
    if (mysql_query(con, sql))
    {
        fprintf(stderr, "Failed to update data : Error:%s\n", mysql_error(con));
        return false;
    }
    return true;
}

bool DAO::delete_info(int &id)
{
    char sql[2048];
    sprintf(sql, "delete from %s where id = %d", table_name, id);
    if (mysql_query(con, sql))
    {
        fprintf(stderr, "Failed to delete data : Error:%s\n", mysql_error(con));
        return false;
    }
    return true;
}

std::vector<Info> DAO::get_info(std::string condition) const
{
    std::vector<Info> info_list;
    char sql[2048];
    sprintf(sql, "select * from %s%s", table_name, condition.c_str());
    if (mysql_query(con, sql))
    {
        fprintf(stderr, "Failed to select data : Error:%s\n", mysql_error(con));
        return {};
    }
    MYSQL_RES *res = mysql_store_result(con);
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(res)))
    {
        Info info(atoi(row[0]), row[1], atoi(row[2]), row[3]);
        info_list.push_back(info);
    }
    mysql_free_result(res);
    return info_list;
}

DAO::DAO()
{
    con = mysql_init(NULL);
    mysql_options(con, MYSQL_SET_CHARSET_NAME, "GBK");
    connect();
}

DAO::~DAO()
{
    mysql_close(con);
}
  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值