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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
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 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
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#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;
}