根據我的以前的文章 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過的數據庫。