点餐系统的设计(二)---数据管理模块代码实现

MySQL的基本操作

我们在这块不是使用sql语言操作数据库,我们使用mysql的c语言代码对数据库进行操作。

mysql API函数

具体的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 DishTableclass 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;
	};

}

猜你喜欢

转载自blog.csdn.net/qq_42708024/article/details/105476851