C++ *** 作MySQL

C++ *** 作MySQL,第1张

项目场景:

C++的课程设计,要用到mysql,花了点时间去查找资料把mysql的 *** 作做了简单的封装。可以直接继承复用。


解决方案:

mysql_operate.h

#pragma once

#ifndef _MYSQL_OPERATE_H_
#define _MYSQL_OPERATE_H_

#include
using 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
/*
	使用方法:
		excute_sql("UPDATE app_produce_data SET is_delete = 1 WHERE id = %d", produce_id)直接输入sql语句
*/
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;
	}
}

/*
	使用方法:
		get_one_request_of_int("SELECT produce_price FROM app_produce_data WHERE id='%d'", produce_id)直接输入sql语句
*/
// 从数据库获取单个数据(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]);  // 返回值
}

/*
	使用方法:
		get_one_request_of_str("SELECT produce_name FROM app_produce_data WHERE id = %d", produce_id), produce_id)直接输入sql语句
*/
// 从数据库获取单个数据(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;


// 数据库 *** 作封装
/*
    1.void excute_sql(const char* format, Args ... args)
        1.获取sql语句执行状态 接收字符串执行sql语句 sql语句执行成功excute_status = 1 失败excute_status = 0
        2.获取结果集数据行数 _res_rows_num
    2.bool display__res(int field_num)  1.打印查询集
*/

// 构造函数
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:%s\n", mysql_error(_mysql));
        return false;
    }
    else
    {
        _state = true;
        return true;
    }
}

// 封装查询语句 返回结果集  执行失败返回nullptr
MYSQL_RES* Mysql_Operate::query() {
    if (_state == false)  // 判断数据库是否连接
    {
        printf("Database not connected\n");
        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 success\n");
    }
    //获取结果集  
    if (!(_res = mysql_store_result(_mysql)))   //获得sql语句结束后返回的结果集  
    {
        //printf("Couldn't get result from %s\n", 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("%10s\t", str_field[i]);
    }
    printf("\n");
    //打印获取的数据  
    while (_column = mysql_fetch_row(_res))   //在已知字段数量情况下,获取并打印下一行  无下一行后mysql_fetch_row返回false结束循环
    {
        for (int i = 0; i < field_num; i++)
        {
            printf("%10s\t", _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: %lld\n", 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("%10s\t", _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;
}








欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/872673.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存