linux下c++写的MySQL操作类

先看 @红薯 写的  Linux下MySQL C++连接操作


这个是简单的MySQL操作封装,已编译通过
编译的时候
加上参数 $(mysql_config --cflags --libs)  或者 -L/usr/lib/mysql -lmysqlclient

看了这个就可以看MySQL连接池的实现。 


代码来自:在LINUX下用C/C++写了个操作MYSQL的类,挺好用。

/*
 * encapsulation_mysql.h
 *
 *  Created on: 2013-3-28
 *      Author: holy
 */

#ifndef ENCAPSULATION_MYSQL_H_
#define ENCAPSULATION_MYSQL_H_

#include <iostream>
#include <cassert>
#include <set>
#include <sys/shm.h>
#include <string>
#include <vector>
#include <stdio.h>
#include <string>
#include <vector>
#include <map>
#include <time.h>
#include <stdlib.h>
#include <memory>
#include <iconv.h>
#include <dlfcn.h>
#include <mysql/mysql.h>

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);
namespace EncapMysql {

class CEncapMysql {
	typedef map<string, int> MapFieldNameIndex;
public:
	CEncapMysql();
	~CEncapMysql();
public:

	int Connect(const char* szDbIp, const char* szUser, const char* szPassword);

	void CloseConnect();

	int SelectQuery(const char* szSQL);

	int ModifyQuery(const char* szSQL);

	const char* GetErrMsg();

	char** FetchRow();

	char* GetField(const char* szFieldName);

////////连接池那个类需要用到这3个函数。  2011-01-20
public:
	void SetUsed();
	void SetIdle();
	bool IsIdle(); //返回 true 标识 Idle
private:
	bool m_bUseIdle;    // true: use;   false:idle

private:

	bool IsConnected();

	void SetConnected(bool bTrueFalse);

	char* GetField(unsigned int iFieldIndex);

	void FreePreResult();

	int ReConnect();

	void SaveParam(const char* szDbIp, const char* szUser,
			const char* szPassword);

public:
	bool m_bConnected;    //数据库连接了吗?   true--已经连接;  false--还没有连接
	char m_szErrMsg[1024]; //函数出错后, 错误信息放在此处
	int m_iFields; //字段个数
	MapFieldNameIndex m_mapFieldNameIndex; //是一个map,  key是字段名,  value是字段索引
public:
	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; //口令
};
} //end of namespace  EncapMysql

#endif /* ENCAPSULATION_MYSQL_H_ */
/*
 * encapsulation_mysql.cpp
 *
 *  Created on: 2013-3-28
 *      Author: holy
 */

#include <stdio.h>
#include <string>
#include <string.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>
#include <set>
#include <map>
#include <stdio.h>
#include <dirent.h>
#include <sys/types.h>
#include "encapsulation_mysql.h"

using namespace std;
using namespace EncapMysql;

CEncapMysql::CEncapMysql() {
	SetConnected(false);
	//把结果集置为空
	m_result = NULL;
	//初始化连接
	mysql_init(&m_connection);
}
CEncapMysql::~CEncapMysql() {
	//释放上一次的结果集
	FreePreResult();
	//关闭数据库连接
	CloseConnect();
}

int CEncapMysql::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) {
		ERRMSG2("%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 CEncapMysql::CloseConnect() {
	//不论m_connection曾经是否连接过, 这样关闭都不会有问题
	mysql_close(&m_connection);
	SetConnected(false);
}

int CEncapMysql::SelectQuery(const char* szSQL) {
	//如果查询串是空指针,则返回
	if (szSQL == NULL) {
		ERRMSG2("%s", "szSQL==NULL");
		return -1;
	}
	//如果还没有连接,则返回
	if (!IsConnected()) {
		ERRMSG2("%s", "还没有建立连接");
		return -2;
	}
	try //这些语句与连接有关,出异常时就重连
	{
		//查询
		if (mysql_real_query(&m_connection, szSQL, strlen(szSQL)) != 0) {
			ERRMSG2("%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) {
			ERRMSG2("%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);
	m_mapFieldNameIndex.clear();
	//取各个字段的属性信息
	MYSQL_FIELD *fields;
	fields = mysql_fetch_fields(m_result);
	//把字段名字和索引保存到一个map中
	for (unsigned int i = 0; i < m_iFields; i++) {
		m_mapFieldNameIndex[fields[i].name] = i;
	}
	return 0;
}

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

char** CEncapMysql::FetchRow() {
	//如果结果集为空,则直接返回空; 调用FetchRow之前, 必须先调用 SelectQuery(...)
	if (m_result == NULL)
		return NULL;
	//从结果集中取出一行
	m_row = mysql_fetch_row(m_result);
	return m_row;
}

char* CEncapMysql::GetField(const char* szFieldName) {
	return GetField(m_mapFieldNameIndex[szFieldName]);
}

char* CEncapMysql::GetField(unsigned int iFieldIndex) {
	//防止索引超出范围
	if (iFieldIndex >= m_iFields)
		return NULL;
	return m_row[iFieldIndex];
}

void CEncapMysql::FreePreResult() {

	if (m_result != NULL) {
		mysql_free_result(m_result);
		m_result = NULL;
	}
}

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

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

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

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

int CEncapMysql::ReConnect() {
	CloseConnect();
	//连接数据库
	if (mysql_real_connect(&m_connection, m_sDbIp.c_str(), m_sUser.c_str(),
			m_sPassword.c_str(), NULL, 0, NULL, 0) == NULL) {
		ERRMSG2("%s", mysql_error(&m_connection));
		return -1;
	}
	//设置连接标志为 true
	SetConnected(true);
	return 0;
}
/////////////////////////  连接池那个类需要用到这3个函数。
void CEncapMysql::SetUsed() {
	m_bUseIdle = true;
}
void CEncapMysql::SetIdle() {
	m_bUseIdle = false;
}
//如果空闲,返回true
bool CEncapMysql::IsIdle() {
	return !m_bUseIdle;
}
/*
 * main.cpp
 *
 *  Created on: 2013-3-26
 *      Author: holy
 */

#include "encapsulation_mysql.h"

using EncapMysql::CEncapMysql;

int main(int argc, char *argv[]) {
	CEncapMysql *con;
	con = new CEncapMysql;
	con->Connect("127.0.0.1", "root", "123456");
	con->SelectQuery("select * from holy.student");
	while (char** r = con->FetchRow())
		printf("%s\t%s\t%s\n", r[0], r[1], r[2]);
	return 0;
}

编程技巧