MySQL的基本操作
我们在这块不是使用sql语言操作数据库,我们使用mysql的c语言代码对数据库进行操作。
具体的mysql API函数讲解,请看上述的博客。我们这里简单列举出几个我们在代码中使用的函数。
-
初始化mysql客户端操作句柄,通过返回值返回操作句柄,mysql可以设置为NULL,表示资源动态分配。
mysql_init(MYSQL *mysql)
返回值:成功返回操作句柄,失败返回NULL。 -
连接服务器
mysql_real_connect(MYSQL *mysql,const char *host,const char *user,const char *passwd,const char* db,unsigned int port,const char *unix_socket,unsigned long client_flag)
mysql:mysql_init返回的操作句柄
host:mysql服务器的IP地址
user:mysql登录用户名
passswd:登录密码
db:初始化要使用的数据库名称
port:服务器的端口信息
unix_socket:套接字文件,通常设置为NULL
client_flag:通常为0
返回值:成功返回操作句柄首地址,失败返回NULL -
选择使用的数据库
int mysql_select_db(MYSQL *mysql,const char *db)
mysql:mysql操作句柄
db:数据库名称
返回值:成功返回0,失败返回非0 -
设置客户端的编码格式
int mysql_set_character_set(MYSQL *mysql,const char *csname)
mysql:操作句柄
csname:通常为utf-8
返回值:成功返回0,失败返回非0 -
向服务器发送数据操作请求
mysql_query(MYSQL *mysql,const char *stmt_str)
mysql:操作句柄
stmt_str:mysql数据操作语句
返回值:成功返回0,失败返回非0 -
获取查询语句的查询结果
MYSQL_RES *mysql_store_result(MYSQL *mysql)
mysql:操作句柄
失败返回NULL -
根据获取的结果遍历查询结果的每一行数据
MYSQL_ROW mysql_fetch_row(MYSQl_RES *result)
result:MYSQL_RES返回的结构化数据 -
返回数据的行数
uint64_t mysql_num_rows(MYSQL_RES *result)
-
返回结果的列数
uint64_t mysql_num_fields(MYSQL_RES *result)
-
释放结果集
void mysql_free_result(MYSQL_RES *result)
-
关闭数据库
mysql_close(MYSQL mysql)
代码实现数据库的操作
- 初始化客户端
- 连接MySQL服务器
- 设置字符编码集
- 查询操作
- 获取查询操作
- 对查询的结果进行遍历
- 关闭数据库
#include<stdio.h>
#include<unistd.h>
#include<string.h>
#include<mysql/mysql.h>
#include<stdlib.h>
int main()
{
MYSQL *mysql = mysql_init(NULL);//初始化操作句柄
//操作句柄,主机地址,用户名,密码,数据库名称,端口,套接字文件,标志
if(mysql_real_connect(mysql,"127.0.0.1","root","123","db_order_sys",0,NULL,0) == NULL)
{
printf("MySQL connect failed\n");
return -1;
}
int ret = mysql_set_character_set(mysql,"utf8");//设置字符编码集
if(ret !=0)
{
printf("set error\n");
return -1;
}
char *sql_str = "select *from tb_dishes;";
ret = mysql_query(mysql,sql_str);
if(ret != 0)
{
printf("sql query error\n");
return -1;
}
MYSQL_RES *res = mysql_store_result(mysql); //获取执行结果
if(res == NULL)
{
printf("result failed\n");
return -1;
}
int row_nums = mysql_num_rows(res);//获取结果行数
int col_nums = mysql_num_fields(res);//获取结果列数
int i = 0,j = 0;
for(;i<row_nums;++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
for(;j<col_nums;++j)
{
printf("%s ",row[j]); //遍历获取每一列的数据
}
printf("\n");
}
mysql_free_result(res);
mysql_close(mysql);
return 0;
}
我们主要设计两个类 class DishTable
与class OrderTable
,一个类用来管理菜单信息,一个用来管理订单信息。由于两个类都需要对数据库进行操作,所以我们需要将数据库的操作进行封装。
数据库的主要功能:
- 初始化
MYSQL *MysqlInit()
- 创建数据库:
mysql_init(NULL);
- 连接数据库:
mysql_real_connect(mysql,MYSQL_SERVER,MYSQL_USER,MYSQL_PASSWD,MYSQL_DB,0,NULL,0)
参数说明:mysql:操作句柄;MYSQL_SERVER:数据库服务器IP地址,MYSQL_USER:登录用户名,MYSQL_PASSWD:登录密码;MYSQL_DB:具体操作的数据库。 - 设置字符编码集:
mysql_set_character_set(mysql,"utf8")
- 创建数据库:
- 语句操作:
bool MysqlQuery(MYSQL *mysql,const std::string &sql)
参数说明:mysql:数据库操作句柄;sql:SQL操作语句 - 销毁数据库:
void MysqlDestroy(MYSQL *mysql)
//由于数据库的销毁操作,在多处地方使用到,这块将其放在前面,也可以只给声明
//数据库的基本操作,都是对数据库API函数的封装。
//数据库的销毁
void MysqlDestroy(MYSQL *mysql)
{
if(mysql != NULL)
{
mysql_close(mysql);
}
return;
}
//数据库的初始化
MYSQL *MysqlInit()
{
MYSQL *mysql = NULL;
mysql = mysql_init(NULL); //创建数据库
if(mysql == NULL)
{
printf("mysql create error\n");
return NULL;
}
//连接服务器
if(mysql_real_connect(mysql,MYSQL_SERVER,MYSQL_USER,MYSQL_PASSWD,MYSQL_DB,0,NULL,0) == NULL)
{
printf("mysql cannet error\n");
MysqlDestroy(mysql);
return NULL;
}
//设置字符编码集
if(mysql_set_character_set(mysql,"utf8")!=0)
{
printf("mysql set character error\n");
MysqlDestroy(mysql);
return NULL;
}
return mysql;
}
//数据库的执行语句
bool MysqlQuery(MYSQL *mysql,const std::string &sql)
{
int ret = mysql_query(mysql,sql.c_str());
if(ret != 0)
{
printf("mysql query error\n");
return false;
}
return true;
}
DishTable类中的功能主要包括:
- 插入:
bool Insert(const Json::Value &dish)
- 查询:
- 查询单个信息:
bool SelectOne(const int dish_id, Json::Value *dish)
参数:通过dish_id进行判断查询,*dish用于将查询到的信息返回。 - 查询全部信息:
bool SelectAll(Json::Value *dishes)
- 查询单个信息:
- 修改:
bool Update(const Json::Value &dish)
- 删除:
bool Delete(const int dish_id)
直接上代码会…,这里我列举一个相对来说不太好理解的代码。
bool SelectAll(Json::Value *dishes) //返回所有信息
{
//DISH_SELECT是一个SQL语句的宏
if(MysqlQuery(_mysql,DISH_SELECTALL) == false) //通过调用MysqlQuery数据库操作的方法,想数据库中发送查询请求
return false;
MYSQL_RES *res = mysql_store_result(_mysql) //用于保存查询结果,MysqlQuery函数执行后的结果信息
if(res == NULL)
{
printf("select all dish error\n");
return false;
}
//num_rows:返回数据信息的条数,我们可以将数据库看成二维数组,num_rows就是数组的行数
int num_rows = mysql_num_rows(res);
for(int i = 0;i<num_rows;++i)
{
MYSQL_ROW row = mysql_fetch_row(res); //相当于二维数组的列数
Json::Value dish_val; //Json序列化查询到的信息,相当于将数据通过<key,value>进行存贮
dish_val["id"] = std::stoi(row[0]);
dish_val["name"] = row[1];
dish_val["price"] = std::stoi(row[2]);
dish_val["uptime"] = row[3];
dishes->append(dish_val); //相当于给二维数组增加一个新行
}
mysql_free_result(res); //释放结果集
return true;
}
注释:在这个SeleteAll函数中,由于查询的是全部信息,所以不需要传入新参数,下面代码中,有的需要传入数据参数,所以需要使用额外的空间进行保存SQL语句。
//先将数据库操作的语句通过宏进行封装
#define DISH_INSERT "insert into tb_dishes(id,name,price,uptime)
#define DISH_SELECTONE "select name,price,uptime from tb_dishes where id=%d;"
#define DISH_SELECTALL "select id,name,price,uptime from tb_dishes;"
#define DISH_UPDATE "update tb_dishes set name='%s',price=%d,uptime=now() where id = %d"
#define DISH_DELETE "delete from tb_dishes where id=%d;"
class DishTable
{
public:
DishTable(MYSQL *mysql):_mysql(mysql)
{
}
bool Insert(const Json::Value &dish)
{
values(null,'%s','%d',now());"
char buf[4096] = {
0}; //保存SQL语句
sprintf(buf,DISH_INSERT,dish["name"].asCString(),dish["price"].asInt());
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
bool SelectOne(const int dish_id, Json::Value *dish) //返回单个菜品信息
{
char buf[4096]= {
0};
sprintf(buf,DISH_SELECTONE,dish_id);
if(MysqlQuery(_mysql,buf) == false)
return false;
MYSQL_RES *res = mysql_store_result(_mysql);
if(res == NULL)
{
printf("select one dish error\n");
return false;
}
int num_row = mysql_num_rows(res); //获取结果行数
if(num_row != 1)
{
printf("one dish result error\n");
return false;
}
for(int i = 0;i<num_row;++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
(*dish)["id"] = dish_id;
(*dish)["name"] = row[0];
(*dish)["price"] = std::stoi(row[1]);
(*dish)["uptime"] = row[2];
}
mysql_free_result(res); //释放结果集
return true;
}
bool SelectAll(Json::Value *dishes) //返回所有信息
{
if(MysqlQuery(_mysql,DISH_SELECTALL) == false)
return false;
MYSQL_RES *res = mysql_store_result(_mysql);
if(res == NULL)
{
printf("select all dish error\n");
return false;
}
int num_rows = mysql_num_rows(res);
for(int i = 0;i<num_rows;++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
Json::Value dish_val;
dish_val["id"] = std::stoi(row[0]);
dish_val["name"] = row[1];
dish_val["price"] = std::stoi(row[2]);
dish_val["uptime"] = row[3];
dishes->append(dish_val);
}
mysql_free_result(res);
return true;
}
bool Update(const Json::Value &dish)
{
char buf[4096] = {
0}; sprintf(buf,DISH_UPDATE,dish["name"].asCString(),dish["price"].asInt(),dish["id"].asInt());
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
bool Delete(const int dish_id)
{
char buf[4096] = {
0};
sprintf(buf,DISH_DELETE,dish_id);
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
private:
MYSQL *_mysql;
};
OrderTable类中的功能主要包括:
- 插入:
bool Insert(const Json::Value &order)
- 查询:
- 查询单个信息:
bool SelectOne(const int order_id, Json::Value *order)
参数:通过dish_id进行判断查询,*dish用于将查询到的信息返回。 - 查询全部信息:
bool SelectAll(Json::Value *orders)
- 查询单个信息:
- 修改:
bool Update(const Json::Value &order)
- 删除:
bool Delete(const int order_id)
//下面的代码我将宏写在具体的位置上,方便进行查看。
class OrderTable
{
public:
OrderTable(MYSQL *mysql):_mysql(mysql)
{
}
bool Insert(const Json::Value &order)
{
#define ORDER_INSERT "insert into tb_order(id,table_id,dishes,status) values(null,%d,'%s',%d);"
char buf[4096];
Json::FastWriter writer;
std::string dishes = writer.write(order["dishes"]);
sprintf(buf,ORDER_INSERT,order["table_id"].asInt(),dishes.c_str(),order["status"].asInt());
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
bool SelectOne(const int order_id, Json::Value *order) //返回单个菜品信息
{
#define ORDER_SELECTONE "select id,table_id,dishes,status from tb_order;"
if(MysqlQuery(_mysql,ORDER_SELECTONE) == false)
return false;
MYSQL_RES *res = mysql_store_result(_mysql);
if(res == NULL)
{
printf("select one order error\n");
return false;
}
int num_rows = mysql_num_rows(res);
for(int i = 0;i<num_rows;++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
Json::Value order_val;
(*order)["id"] = std::stoi(row[0]);
(*order)["table_id"] = std::stoi(row[1]);
Json::Value dishes;
Json::Reader reader;
reader.parse(row[2],dishes);
(*order)["dishes"] = dishes;
(*order)["status"] = std::stoi(row[3]);
}
mysql_free_result(res);
return true;
}
bool SelectAll(Json::Value *orders) //返回所有信息
{
#define ORDER_SELECTALL "select id,table_id,dishes,status from tb_order;"
if(MysqlQuery(_mysql,ORDER_SELECTALL) == false)
return false;
MYSQL_RES *res = mysql_store_result(_mysql);
if(res == NULL)
{
printf("select all order error\n");
return false;
}
int num_rows = mysql_num_rows(res);
for(int i = 0;i<num_rows;++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
Json::Value order_val;
order_val["id"] = std::stoi(row[0]);
order_val["table_id"] = std::stoi(row[1]);
Json::Value dishes;
Json::Reader reader;
reader.parse(row[2],dishes);
order_val["dishes"] = dishes;
order_val["status"] = std::stoi(row[3]);
orders->append(order_val);
}
mysql_free_result(res);
return true;
}
bool Update(const Json::Value &order)
{
#define ORDER_UPDATE "update tb_order set table_id=%d,dishes='%s',status=%d where id = %d;"
char buf[4096] = {
0};
Json::Value dishes = order["dishes"];
Json::FastWriter writer;
std::string str_dishes = writer.write(dishes);
sprintf(buf,ORDER_UPDATE,order["table_id"].asInt(),str_dishes.c_str(),order["status"].asInt(),order["id"].asInt());
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
bool Delete(const int order_id)
{
#define ORDER_DELETE "delete from tb_order where id=%d;"
char buf[4096] = {
0};
sprintf(buf,ORDER_DELETE,order_id);
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
private:
MYSQL *_mysql;
};
//完整的代码,这里我们只写了一个.hpp文件,具体的.cpp文件需要搭配网络通信
#include<cstdio>
#include<iostream>
#include<mysql/mysql.h>
#include<string>
#include<jsoncpp/json/json.h>
#define MYSQL_SERVER "127.0.0.1"
#define MYSQL_USER "root"
#define MYSQL_PASSWD "123"
#define MYSQL_DB "db_order_sys"
namespace order_sys
{
extern void MysqlDestroy(MYSQL *mysql);
//数据库的基本操作
//1:初始化数据库
MYSQL *MysqlInit()
{
MYSQL *mysql = NULL;
mysql = mysql_init(NULL);
if(mysql == NULL)
{
printf("mysql create error\n");
return NULL;
}
//连接服务器
if(mysql_real_connect(mysql,MYSQL_SERVER,MYSQL_USER,MYSQL_PASSWD,MYSQL_DB,0,NULL,0) == NULL)
{
printf("mysql cannet error\n");
MysqlDestroy(mysql);
return NULL;
}
//设置字符编码集
if(mysql_set_character_set(mysql,"utf8")!=0)
{
printf("mysql set character error\n");
MysqlDestroy(mysql);
return NULL;
}
return mysql;
}
//数据库的销毁
void MysqlDestroy(MYSQL *mysql)
{
if(mysql != NULL)
{
mysql_close(mysql);
}
return;
}
//数据库的执行语句
bool MysqlQuery(MYSQL *mysql,const std::string &sql)
{
int ret = mysql_query(mysql,sql.c_str());
if(ret != 0)
{
printf("mysql query error\n");
return false;
}
return true;
}
class DishTable
{
public:
DishTable(MYSQL *mysql):_mysql(mysql)
{
}
bool Insert(const Json::Value &dish)
{
#define DISH_INSERT "insert into tb_dishes(id,name,price,uptime) values(null,'%s','%d',now());"
char buf[4096] = {
0};
sprintf(buf,DISH_INSERT,dish["name"].asCString(),dish["price"].asInt());
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
bool SelectOne(const int dish_id, Json::Value *dish) //返回单个菜品信息
{
#define DISH_SELECTONE "select name,price,uptime from tb_dishes where id=%d;"
char buf[4096]= {
0};
sprintf(buf,DISH_SELECTONE,dish_id);
if(MysqlQuery(_mysql,buf) == false)
return false;
MYSQL_RES *res = mysql_store_result(_mysql);
if(res == NULL)
{
printf("select one dish error\n");
return false;
}
int num_row = mysql_num_rows(res); //获取结果行数
if(num_row != 1)
{
printf("one dish result error\n");
return false;
}
for(int i = 0;i<num_row;++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
(*dish)["id"] = dish_id;
(*dish)["name"] = row[0];
(*dish)["price"] = std::stoi(row[1]);
(*dish)["uptime"] = row[2];
}
mysql_free_result(res); //释放结果集
return true;
}
bool SelectAll(Json::Value *dishes) //返回所有信息
{
#define DISH_SELECTALL "select id,name,price,uptime from tb_dishes;"
if(MysqlQuery(_mysql,DISH_SELECTALL) == false)
return false;
MYSQL_RES *res = mysql_store_result(_mysql);
if(res == NULL)
{
printf("select all dish error\n");
return false;
}
int num_rows = mysql_num_rows(res);
for(int i = 0;i<num_rows;++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
Json::Value dish_val;
dish_val["id"] = std::stoi(row[0]);
dish_val["name"] = row[1];
dish_val["price"] = std::stoi(row[2]);
dish_val["uptime"] = row[3];
dishes->append(dish_val);
}
mysql_free_result(res);
return true;
}
bool Update(const Json::Value &dish)
{
#define DISH_UPDATE "update tb_dishes set name='%s',price=%d,uptime=now() where id = %d"
char buf[4096] = {
0};
sprintf(buf,DISH_UPDATE,dish["name"].asCString(),dish["price"].asInt(),dish["id"].asInt());
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
bool Delete(const int dish_id)
{
#define DISH_DELETE "delete from tb_dishes where id=%d;"
char buf[4096] = {
0};
sprintf(buf,DISH_DELETE,dish_id);
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
private:
MYSQL *_mysql;
};
class OrderTable
{
public:
OrderTable(MYSQL *mysql):_mysql(mysql)
{
}
bool Insert(const Json::Value &order)
{
#define ORDER_INSERT "insert into tb_order(id,table_id,dishes,status) values(null,%d,'%s',%d);"
char buf[4096];
Json::FastWriter writer;
std::string dishes = writer.write(order["dishes"]);
sprintf(buf,ORDER_INSERT,order["table_id"].asInt(),dishes.c_str(),order["status"].asInt());
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
bool SelectOne(const int order_id, Json::Value *order) //返回单个菜品信息
{
#define ORDER_SELECTONE "select id,table_id,dishes,status from tb_order;"
if(MysqlQuery(_mysql,ORDER_SELECTONE) == false)
return false;
MYSQL_RES *res = mysql_store_result(_mysql);
if(res == NULL)
{
printf("select one order error\n");
return false;
}
int num_rows = mysql_num_rows(res);
for(int i = 0;i<num_rows;++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
Json::Value order_val;
(*order)["id"] = std::stoi(row[0]);
(*order)["table_id"] = std::stoi(row[1]);
Json::Value dishes;
Json::Reader reader;
reader.parse(row[2],dishes);
(*order)["dishes"] = dishes;
(*order)["status"] = std::stoi(row[3]);
}
mysql_free_result(res);
return true;
}
bool SelectAll(Json::Value *orders) //返回所有信息
{
#define ORDER_SELECTALL "select id,table_id,dishes,status from tb_order;"
if(MysqlQuery(_mysql,ORDER_SELECTALL) == false)
return false;
MYSQL_RES *res = mysql_store_result(_mysql);
if(res == NULL)
{
printf("select all order error\n");
return false;
}
int num_rows = mysql_num_rows(res);
for(int i = 0;i<num_rows;++i)
{
MYSQL_ROW row = mysql_fetch_row(res);
Json::Value order_val;
order_val["id"] = std::stoi(row[0]);
order_val["table_id"] = std::stoi(row[1]);
Json::Value dishes;
Json::Reader reader;
reader.parse(row[2],dishes);
order_val["dishes"] = dishes;
order_val["status"] = std::stoi(row[3]);
orders->append(order_val);
}
mysql_free_result(res);
return true;
}
bool Update(const Json::Value &order)
{
#define ORDER_UPDATE "update tb_order set table_id=%d,dishes='%s',status=%d where id = %d;"
char buf[4096] = {
0};
Json::Value dishes = order["dishes"];
Json::FastWriter writer;
std::string str_dishes = writer.write(dishes);
sprintf(buf,ORDER_UPDATE,order["table_id"].asInt(),str_dishes.c_str(),order["status"].asInt(),order["id"].asInt());
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
bool Delete(const int order_id)
{
#define ORDER_DELETE "delete from tb_order where id=%d;"
char buf[4096] = {
0};
sprintf(buf,ORDER_DELETE,order_id);
if(MysqlQuery(_mysql,buf) == false)
return false;
return true;
}
private:
MYSQL *_mysql;
};
}