封裝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:\n");
		if( strcmp( "quit", gets(buffer)) != 0 )
		{
			
			if(  (char) '1'== buffer[0] ){
				mysql.SelectQuery(buffer+1);
				
 			}else{
				mysql.ModifyQuery(buffer+1);
				printf("Modify\n");
			}

		}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"\r\n" , __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!\r\n", 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  !!!***@\r\n");
			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  !!!***@!@\r\n");
		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("\n------------------------------------------------\n");
	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("\n");
	
	}

	printf("\n------------------------------------------------\n");
}


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!!!***\r\n");
		ReConnect();
		return -5;
	}
	return 0;
}

注:

對於輸入的MySQL命令錯誤的情況下,程序會連接一遍,在程序關閉過後用於連接的關鍵字【MYSQL m_connection; 】必須要初始化,否則程序會出錯。

還有,重連過後,必須重新USE XXXXX; 因爲重新連接那裏並沒有自動連接你之前USE過的數據庫。









發佈了32 篇原創文章 · 獲贊 1 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章