1.环境搭建
在这里,我将使用vscode来搭建MySQL的编程环境。
首先,下载MySQL,配置好系统环境变量并运行MySQL数据库。
接着,vscode扩展中搜索并下载MySQL与MySQL 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);
}