C++的课程设计,要用到mysql,花了点时间去查找资料把mysql的操作做了简单的封装。可以直接继承复用。
解决方案:
mysql_operate.h
#pragma once #ifndef _MYSQL_OPERATE_H_ #define _MYSQL_OPERATE_H_ #includeusing namespace std; #include #include #include #include extern const int MAX_SQL_SENTENCE_LENGTH; class Mysql_Operate { public: Mysql_Operate(); ~Mysql_Operate(); //连接数据库 参数为ip 用户名 密码 数据库名 端口 bool connect(const char* HOST, const char* USER, const char* PASSWORD, const char* DATABASE_NAME, const int PORT); // 封装后的操作函数 template void excute_sql(const char* format, Args ... args); // 可直接执行sql语句 template int get_one_request_of_int(const char* format, Args ... args); // 从数据库获取单个数据(int) template char* get_one_request_of_str(const char* format, Args ... args); // 从数据库获取单个数据(str) bool display__res(); // 打印结果集 bool query_table(const char* table_name); //查询并打印表 参数为表名 这个函数不能使用别名 便捷的打印表的数据(可用来测试) 直接输入表的名称 // 初步封装的函数 int get__res_field_num(); //获取结果集的字段数 int get__res_row_num(); // 返回结果集合中的行的数量 查询集为空返回0 MYSQL_RES* query(); // 执行查询语句 返回查询集 底层操作函数(不直接调用) int get_tag_id(const char*); // 获取表的最后一行的id+1 (新行的id) protected: bool _state; //连接状态 true为已连接 MYSQL* _mysql; //mysql连接 MYSQL_RES* _res; //这个结构代表返回行的一个查询结果集 MYSQL_ROW _column; //一个行数据的类型安全(type-safe)的表示,表示数据行的列 char* _query; //查询语句 有的查询语句过长会导致内存不够 分配大一点 int excute_status; // sql语句执行状态 成功、失败 int _res_rows_num; // 结果集合中的行的数量 为0说明结果集为空 int field_num; // 结果集中字段数 string exit_params; // 退出操作参数 }; char* get_datetime(); // 返回字符串日期时间 往数据库录入当前时间 // 封装的执行sql语句 执行成功返回1 失败返回0 template void Mysql_Operate::excute_sql(const char* format, Args ... args) { excute_status = 0; // 初始化状态参数 _res_rows_num = 0; // 初始化结果集数据行数 field_num = 0; sprintf_s(_query, MAX_SQL_SENTENCE_LENGTH, format, args...); if (query()) { excute_status = 1; // sql语句执行成功 excute_status = 1 _res_rows_num = get__res_row_num(); // 结果集数据行数 field_num = get__res_field_num(); } else { excute_status = 0; _res_rows_num = 0; field_num = 0; } } // 从数据库获取单个数据(int) template int Mysql_Operate::get_one_request_of_int(const char* format, Args ... args) { excute_sql(format, args...); _column = mysql_fetch_row(_res); // 获取第一行 //cout << atoi(_column[0]); return atoi(_column[0]); // 返回值 } // 从数据库获取单个数据(str) template char* Mysql_Operate::get_one_request_of_str(const char* format, Args ... args) { excute_sql(format, args...); _column = mysql_fetch_row(_res); // 获取第一行 //cout << _column[0]; return _column[0]; // 返回值 } #endif // _MYSQL_OPERATE_H_
mysql_operate.cpp
# include "mysql_operate.h" # include# include const int MAX_SQL_SENTENCE_LENGTH = 1000; // 数据库操作封装 // 构造函数 Mysql_Operate::Mysql_Operate() { _state = false; // 连接状态 _mysql = new MYSQL; _query = new char[MAX_SQL_SENTENCE_LENGTH]; // 分配内存 _res = nullptr; // 初始化结果集 _column = nullptr; // 初始化结果行 memset(_query, NULL, sizeof(_query)); // 初始化查询语句 connect("localhost", "root", "898678", "supermarket_data", 3306); //连接数据库 参数为ip、用户名、密码、数据库名、端口 _res_rows_num = 0; // 结果集合中的行的数量 为0说明结果集为空 field_num = 0; // 结果集中字段数 exit_params = "0"; // 退出操作参数 } // 析构函数 Mysql_Operate::~Mysql_Operate() { } // 连接数据库 bool Mysql_Operate::connect(const char* HOST, const char* USER, const char* PASSWORD, const char* DATABASE_NAME, const int PORT) { if (_state == true) { cout << "Connected succeed" << endl; return true; } //初始化mysql mysql_init(_mysql); //返回false则连接失败,返回true则连接成功 if (!(mysql_real_connect(_mysql, HOST, USER, PASSWORD, DATABASE_NAME, PORT, NULL, 0))) // 主机用户名、密码、数据库名、端口号 { printf("Error connecting to database:%sn", mysql_error(_mysql)); return false; } else { _state = true; return true; } } // 封装查询语句 返回结果集 执行失败返回nullptr MYSQL_RES* Mysql_Operate::query() { if (_state == false) // 判断数据库是否连接 { printf("Database not connectedn"); return false; } //设置编码格式(SET NAMES GBK也行),否则cmd下中文乱码 mysql_query(_mysql, "set names gbk"); MYSQL_RES* error = nullptr; // 获取查询结果 并进行查询结果判断 if (mysql_query(_mysql, _query)) //执行SQL语句 { printf("Query failed (%s)n", mysql_error(_mysql)); return error; } else { //printf("query successn"); } //获取结果集 if (!(_res = mysql_store_result(_mysql))) //获得sql语句结束后返回的结果集 { //printf("Couldn't get result from %sn", mysql_error(_mysql)); //return error; } if (_res == nullptr) { _res = new MYSQL_RES; // 区分 插入、更新数据时无返回结果集导致无法sql语句判断是否执行成功 不让_res == error } return _res; } // 打印结果集 bool Mysql_Operate::display__res() { char* str_field[MAX_SQL_SENTENCE_LENGTH]; // 字段名 for (int i = 0; i < field_num; i++) //在获得字段数量的情况下获取字段名 { str_field[i] = mysql_fetch_field(_res)->name; // 返回下一个表字段名 } //打印字段名 打印表的第一行字段名 for (int i = 0; i < field_num; i++) { printf("%10st", str_field[i]); } printf("n"); //打印获取的数据 while (_column = mysql_fetch_row(_res)) //在已知字段数量情况下,获取并打印下一行 无下一行后mysql_fetch_row返回false结束循环 { for (int i = 0; i < field_num; i++) { printf("%10st", _column[i]); //column是列数组 一行包括多列 } printf("n"); } return true; } // 返回结果集合中的行的数量 查询集为空返回0 int Mysql_Operate::get__res_row_num() { return mysql_num_rows(_res); } // 返回结果集中的字段数 int Mysql_Operate::get__res_field_num() { return mysql_field_count(_mysql); } // 查询表 直接传入表名 bool Mysql_Operate::query_table(const char* table_name) { //查询内容 if (!strcmp(table_name, "app_produce_data")) { // 如果为商品信息表 增加是否删除判断 excute_sql("select * from %s WHERe is_delete = 0", table_name); //执行查询语句 } else { excute_sql("select * from %s", table_name); //执行查询语句 } //打印数据行数 printf("number of dataline returned: %lldn", mysql_affected_rows(_mysql)); // 打印表数据 display__res(); return true; } // 获取表的最后一行的id 在此基础上加1 返回新的一行的id int Mysql_Operate::get_tag_id(const char* c) { //查询内容 excute_sql("SELECt id FROM %s ORDER BY id DESC LIMIT 1", c); _column = mysql_fetch_row(_res); //printf("%10st", _column[0]); //column是列数组 if (_column == nullptr) { return 1; } int row_num = atoi(_column[0]); return row_num + 1; } //int to string string inttostring(int in) { stringstream ss; string str; ss << in; ss >> str; return str; } // 返回字符串日期时间 char* get_datetime() { //get the current time CTime t = CTime::GetCurrentTime(); string mytime = inttostring(t.GetYear()) + "-" + inttostring(t.GetMonth()) + "-" + inttostring(t.GetDay()) + " " + inttostring(t.GetHour()) + ":" + inttostring(t.GetMinute()) + ":" + inttostring(t.GetSecond()); //cout << mytime << endl; static char sdate[30]; strcpy_s(sdate, mytime.c_str()); //cout << size(sdate) << endl; return sdate; }



