封装MySQL C API 基本操作

根据我的以前的文章 http://blog.csdn.net/skyhuangdan/article/details/21099929 链接数据库成功后进行封装。

我封装类使用的是VS2005下的win32控制台应用程序编写,预编译头文件了的。


所以要在 stdafx.h 里面加入 :

#include "CMySQL.h"



现在代码奉上:

main函数代码:mysql2.cpp

// mysql2.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"




int main()
{
	CMySQL mysql;
	int re = mysql.Connect("localhost", "root", "123456");


	mysql.ReConnect();


	char buffer[1024] = {0};
	while(1)
	{
		memset(buffer, 0, 1024);
		printf("please input cmd:
");
		if( strcmp( "quit", gets(buffer)) != 0 )
		{
			
			if(  (char) '1'== buffer[0] ){
				mysql.SelectQuery(buffer+1);
				
 			}else{
				mysql.ModifyQuery(buffer+1);
				printf("Modify
");
			}

		}else
			break;
		
	}


	getchar();
}




CMySQL.h


#pragma once



#include <windows.h>
#include <my_global.h>
#include <mysql.h>
#include <iostream>

using namespace std;

/*
#define ERRMSG1(fmt,...)  ; sprintf(m_szErrMsg, fmt, __VA_ARGS__);
#define ERRMSG2(fmt,args...)  ; sprintf(m_szErrMsg, "[%s 第 %d 行 ]; "fmt"
" , __FILE__, __LINE__, ##args);
*/
class CMySQL
{
public:
	CMySQL(void);
public:
	~CMySQL(void);

public:
	bool m_bConnected;    //数据库连接了吗?   true--已经连接;  false--还没有连接
	char m_szErrMsg[1024]; //函数出错后, 错误信息放在此处
	int m_iFields; //字段个数

	MYSQL m_connection; //连接
	MYSQL_RES* m_result; //结果集指针
	MYSQL_ROW m_row; //一行,  typedef char **MYSQL_ROW;

private:
	string m_sDbIp; //数据库服务器IP
	string m_sUser; //用户名
	string m_sPassword; //口令



public:

	int Connect(const char* szDbIp, const char* szUser, const char* szPassword);
	//关闭连接,无论之前是否已经连接,使用这个函数都不会有问题
	void CloseConnect();
	//判断是否连接
	bool IsConnected();
	//连接标志
	void SetConnected(bool bTrueFalse );
	//重新连接
	int ReConnect();


	//用于执行查询命令,并且把查询到的结果集保存到m_result结果集里面
	//!!此函数调用SelectPrint()函数!!
	int SelectQuery(const char* szSQL);


	//只是执行SQL命令
	int ModifyQuery(const char* szSQL);

	//返回错误信息
	const char* GetErrMsg();
	
	//保存连接参数
	void SaveParam(const char* szDbIp, const char* szUser, const char* szPassword);

	//释放上次的结果
	void FreePreResult();

	//显示结果?
	void PrintSelect();

};




CMySQL.cpp:

#include "StdAfx.h"
#include "CMySQL.h"

CMySQL::CMySQL(void)
{
	SetConnected(false);
	//把结果集置空
	m_result = NULL;
	//初始化连接
	mysql_init(&m_connection);

}

CMySQL::~CMySQL(void)
{
	//释放上一次的结果集
	FreePreResult();
	//关闭数据库连接
	CloseConnect();

}


int CMySQL::Connect(const char* szDbIp, const char* szUser, const char* szPassword) 
{
	SaveParam(szDbIp, szUser, szPassword);
	//先判断释放已连接,防止重复连接
	if (IsConnected())
		return 0;
	//连接数据库
	if (mysql_real_connect( &m_connection, szDbIp, szUser, szPassword, NULL, 0,NULL, 0) == NULL) 
	{
		 sprintf(m_szErrMsg,"%s" ,mysql_error(&m_connection));
		return -1;	
	
	}
	printf("[mysql] conn to %s [user:%s] succ!
", szDbIp, szUser);
	//设置连接标志为 true
	SetConnected(true);
	return 0;
}

void CMySQL::CloseConnect() 
{
	//不论m_connection曾经是否连接过, 这样关闭都不会有问题
	mysql_close(&m_connection);
	SetConnected(false);
}



bool CMySQL::IsConnected() {
	return m_bConnected;
}



void CMySQL::SetConnected(bool bTrueFalse) 
{
	m_bConnected = bTrueFalse;
}



void CMySQL::FreePreResult()
{
	if (m_result != NULL) 
	{
		mysql_free_result(m_result);
		m_result = NULL;
	}


}


int CMySQL::SelectQuery(const char* szSQL)
{
	//如果查询串是空指针,则返回
	if (szSQL == NULL) {
		sprintf(m_szErrMsg,"%s", "szSQL==NULL");
		return -1;
	}
	//如果还没有连接,则返回
	if (!IsConnected()) {
		sprintf(m_szErrMsg,"%s" , "还没有建立连接");
		return -2;
	}
	try //这些语句与连接有关,出异常时就重连
	{
		//查询
		if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0)
		{
			sprintf(m_szErrMsg,"%s" , mysql_error(&m_connection));
			printf("%s", mysql_error(&m_connection));
			printf("ReConnect()  is called, select111  !!!***@
");
			int nRet = ReConnect();
			if (nRet != 0)
				return -3;
			//
			if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0)
				return -33;
			//
		}
		//释放上一次的结果集
		FreePreResult();
		//取结果集
		m_result = mysql_store_result(&m_connection);
		if (m_result == NULL) {
			sprintf(m_szErrMsg,"%s" , mysql_error(&m_connection));
			return -4;
		}
	} catch (...) {
		printf("ReConnect()  is called, select  !!!***@!@
");
		ReConnect();
		return -5;
	}
	//取字段的个数
	m_iFields = mysql_num_fields(m_result);

	//查询完过后进行打印出来
	this->PrintSelect();
	return 0;
}





int CMySQL::ReConnect() {
	CloseConnect();
	//连接数据库

	SetConnected(false);
	//把结果集置空
	m_result = NULL;
	//初始化连接
	mysql_init(&m_connection);

	if (mysql_real_connect(&m_connection, m_sDbIp.c_str(), m_sUser.c_str(),m_sPassword.c_str(), NULL, 0, NULL, 0) == NULL)
	{
		sprintf(m_szErrMsg,"%s" , mysql_error(&m_connection));
		return -1;
	}
	//设置连接标志为 true
	SetConnected(true);
	return 0;
}



const char* CMySQL::GetErrMsg() {
	return m_szErrMsg;
}


void CMySQL::SaveParam(const char* szDbIp, const char* szUser,
		const char* szPassword) {
	m_sDbIp = szDbIp; //数据库服务器IP
	m_sUser = szUser; //用户名
	m_sPassword = szPassword; //口令
}



void CMySQL::PrintSelect()
{
	printf("
------------------------------------------------
");
	int num_fields = mysql_num_fields(m_result);
	while ( m_row = mysql_fetch_row( m_result) )
	{
		for( int i = 0; i < num_fields; i++ )
		{
			if(m_row[i])
				printf("%s  ", m_row[i]);
			else
				printf("NULL");
		
		}
		printf("
");
	
	}

	printf("
------------------------------------------------
");
}


int CMySQL::ModifyQuery(const char* szSQL) {
	//如果查询串是空指针,则返回
	if (szSQL == NULL) {
		sprintf(m_szErrMsg,"%s", "szSQL==NULL");
		return -1;
	}
	//如果还没有连接,则返回
	if (!IsConnected()) {
		sprintf(m_szErrMsg,"%s", "还没有建立连接");
		return -2;
	}
	try //这些语句与连接有关,出异常时就重连
	{
		//查询, 实际上开始真正地修改数据库
		if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0) {
			sprintf(m_szErrMsg,"%s", mysql_error(&m_connection));
			return -3;
		}
	} catch (...) {
		printf("ReConnect()  is called  ,modify!!!***
");
		ReConnect();
		return -5;
	}
	return 0;
}

注:

对于输入的MySQL命令错误的情况下,程序会连接一遍,在程序关闭过后用于连接的关键字【MYSQL m_connection; 】必须要初始化,否则程序会出错。

还有,重连过后,必须重新USE XXXXX; 因为重新连接那里并没有自动连接你之前USE过的数据库。









原文地址:https://www.cnblogs.com/skyhuangdan/p/5486793.html