您的位置:首页 > 运维架构 > Linux

用c++ 操作mysql 数据库类(for linux or windows and others)

2011-01-19 11:28 537 查看
最近开发个项目,因为要用到mysql数据库,作为对数据的后台支持,于是就找了些关于mysql c api的资料,发现不像以前用ado那么顺手,于是就按着操作ado的习惯,写了几个操作mysql数据库的类,用起来感觉还比较方便,小弟不敢独享,于 是就贴在了自己的blog上,与大家分享,希望大家多多测试,增加更多的功能 ........

忠告:这几个类对处理不是很大数据量的操作是比较理想的, 但对于特大型的数据查询时就不太适合了,因为我将查询到的数据直接放入了内存,如果一次查询的数据量超过了几百M,而你的内存没有足够大,就应该想想别的办法了!也希望大家帮忙改进,谢谢!

希望能帮你从繁忙的工作中解放出来,因为我们都是辛苦的程序员,共同进步,互相学习,我一直所希望的!

good luck

源码:

/*

* project:

* 通用模块 ( 用 c++ 处理 mysql 数据库类,像ADO )

*

* description:

*

* 通过DataBase,RecordSet,Record,Field类,实现对mysql数据库的操作

* 包括连接、修改、添加、删除、查询等等,像ADO一样操作数据库,使

* 用方便

*

* ( the end of this file have one sample,

* welcom to use... )

*

*

* file:zlb_mysql.h

*

* author: @ zlb

*

* time:2005-12-12

*

*

*

--*/

#ifndef ZLB_MYSQL_H

#define ZLB_MYSQL_H

#include "mysql.h"

#include <iostream>

#include <vector>

#include <string>

using namespace std;

namespace zlb_mysql{

/*

* 字段操作

*/

class Field

{

public :

/* 字段名称 */

vector<string> m_name;

/* 字段类型 */

vector<enum_field_types> m_type;

public :

Field();

~Field();

/* 是否是数字 */

bool IsNum(int num);

/* 是否是数字 */

bool IsNum(string num);

/* 是否是日期 */

bool IsDate(int num);

/* 是否是日期 */

bool IsDate(string num);

/* 是否是字符 */

bool IsChar(int num);

/* 是否是字符 */

bool IsChar(string num);

/* 是否为二进制数据 */

bool IsBlob(int num);

/* 是否为二进制数据 */

bool IsBlob(string num);

/* 得到指定字段的序号 */

int GetField_NO(string field_name);

};

/*

* 1 单条记录

* 2 [int ]操作 [""]操作

*/

class Record

{

public:

/* 结果集 */

vector<string> m_rs;

/* 字段信息 占用4字节的内存 当记录数很大是回产生性能问题 */

Field *m_field;

public :

Record(){};

Record(Field* m_f);

~Record();

void SetData(string value);

/* [""]操作 */

string operator[](string s);

string operator[](int num);

/* null值判断 */

bool IsNull(int num);

bool IsNull(string s);

/* 用 value tab value 的形式 返回结果 */

string GetTabText();

};

/*

* 1 记录集合

* 2 [int ]操作 [""]操作

* 3 表结构操作

* 4 数据的插入修改

*/

class RecordSet

{

private :

/* 记录集 */

vector<Record> m_s;

/* 游标位置*/

unsigned long pos;

/* 记录数 */

int m_recordcount;

/* 字段数 */

int m_field_num;

/* 字段信息 */

Field m_field;

MYSQL_RES * res ;

MYSQL_FIELD * fd ;

MYSQL_ROW row;

MYSQL* m_Data ;

public :

RecordSet();

RecordSet(MYSQL *hSQL);

~RecordSet();

/* 处理返回多行的查询,返回影响的行数 */

int ExecuteSQL(const char *SQL);

/* 得到记录数目 */

int GetRecordCount();

/* 得到字段数目 */

int GetFieldNum();

/* 向下移动游标 */

long MoveNext();

/* 移动游标 */

long Move(long length);

/* 移动游标到开始位置 */

bool MoveFirst();

/* 移动游标到结束位置 */

bool MoveLast();

/* 获取当前游标位置 */

unsigned long GetCurrentPos()const;

/* 获取当前游标的对应字段数据 */

bool GetCurrentFieldValue(const char * sFieldName,char *sValue);

bool GetCurrentFieldValue(const int iFieldNum,char *sValue);

/* 获取游标的对应字段数据 */

bool GetFieldValue(long index,const char * sFieldName,char *sValue);

bool GetFieldValue(long index,int iFieldNum,char *sValue);

/* 是否到达游标尾部 */

bool IsEof();

/* 返回字段 */

Field* GetField();

/* 返回字段名 */

const char * GetFieldName(int iNum);

/* 返回字段类型 */

const int GetFieldType(char * sName);

const int GetFieldType(int iNum);

/* 返回指定序号的记录 */

Record operator[](int num);

};

/*

* 1 负责数据库的连接关闭

* 2 执行sql 语句(不返回结果)

* 3 处理事务

*/

class DataBase

{

public :

DataBase();

~DataBase();

private :

/* msyql 连接句柄 */

MYSQL* m_Data;

public :

/* 返回句柄 */

MYSQL * GetMysql();

/* 连接数据库 */

int Connect(string host, string user,

string passwd, string db,

unsigned int port,

unsigned long client_flag);

/* 关闭数据库连接 */

void DisConnect();

/* 执行非返回结果查询 */

int ExecQuery(string sql);

/* 测试mysql服务器是否存活 */

int Ping();

/* 关闭mysql 服务器 */

int ShutDown();

/* 主要功能:重新启动mysql 服务器 */

int ReBoot();

/*

* 说明:事务支持InnoDB or BDB表类型

*/

/* 主要功能:开始事务 */

int Start_Transaction();

/* 主要功能:提交事务 */

int Commit();

/* 主要功能:回滚事务 */

int Rollback();

/* 得到客户信息 */

const char * Get_client_info();

/* 主要功能:得到客户版本信息 */

const unsigned long Get_client_version();

/* 主要功能:得到主机信息 */

const char * Get_host_info();

/* 主要功能:得到服务器信息 */

const char * Get_server_info();

/*主要功能:得到服务器版本信息*/

const unsigned long Get_server_version();

/*主要功能:得到 当前连接的默认字符集*/

const char * Get_character_set_name();

/* 主要功能返回单值查询 */

char * ExecQueryGetSingValue(string sql);

/* 得到系统时间 */

const char * GetSysTime();

/* 建立新数据库 */

int Create_db(string name);

/* 删除制定的数据库*/

int Drop_db(string name);

};

};

#endif //ZLB_MYSQL_H

/*

* project:

* 通用模块 ( 用 c++ 处理 mysql 数据库类,像ADO )

*

* description:

*

* 通过DataBase,RecordSet,Record,Field类,实现对mysql数据库的操作

* 包括连接、修改、添加、删除、查询等等,像ADO一样操作数据库,使

* 用方便

*

* ( the end of this file have one sample,

* welcom to use... )

*

*

* file:zlb_mysql.cpp

*

* author: @ zlb

*

* time:2005-12-12

*

*

*

--*/

#include "stdafx.h"

#include "zlb_mysql.h"

namespace zlb_mysql{

/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */

/*

* 字段操作

*/

Field::Field(){}

Field::~Field(){}

/*

* 是否是数字

*/

bool Field::IsNum(int num)

{

if(IS_NUM(m_type[num]))

return true;

else

return false;

}

/*

* 是否是数字

*/

bool Field::IsNum(string num)

{

if(IS_NUM(m_type[GetField_NO(num)]))

return true;

else

return false;

}

/*

* 是否是日期

*/

bool Field::IsDate(int num)

{

if( FIELD_TYPE_DATE == m_type[num] ||

FIELD_TYPE_DATETIME == m_type[num] )

return true;

else

return false;

}

/* 是否是日期 */

bool Field::IsDate(string num)

{

int temp;

temp=GetField_NO(num);

if(FIELD_TYPE_DATE == m_type[temp] ||

FIELD_TYPE_DATETIME == m_type[temp] )

return true;

else

return false;

}

/*

* 是否是字符

*/

bool Field::IsChar(int num)

{

if(m_type[num]==FIELD_TYPE_STRING ||

m_type[num]==FIELD_TYPE_VAR_STRING ||

m_type[num]==FIELD_TYPE_CHAR )

return true;

else

return false;

}

/*

* 是否是字符

*/

bool Field::IsChar(string num)

{

int temp;

temp=this->GetField_NO (num);

if(m_type[temp]==FIELD_TYPE_STRING ||

m_type[temp]==FIELD_TYPE_VAR_STRING ||

m_type[temp]==FIELD_TYPE_CHAR )

return true;

else

return false;

}

/*

* 是否为二进制数据

*/

bool Field::IsBlob(int num)

{

if(IS_BLOB(m_type[num]))

return true;

else

return false;

}

/*

* 是否为二进制数据

*/

bool Field::IsBlob(string num)

{

if(IS_BLOB(m_type[GetField_NO(num)]))

return true;

else

return false;

}

/*

* 得到指定字段的序号

*/

int Field::GetField_NO(string field_name)

{

for(unsigned int i=0;i<m_name.size ();i++)

{

if(!m_name[i].compare (field_name))

return i;

}

return -1;

}

/*-----------------------------------------------------*/

/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */

/*

* 1 单条记录

* 2 [int ]操作 [""]操作

*/

Record::Record(Field * m_f)

{

m_field =m_f;

}

Record::~Record(){};

void Record::SetData(string value)

{

m_rs.push_back (value);

}

/* [""]操作 */

string Record::operator[](string s)

{

return m_rs[m_field->GetField_NO(s)];

}

string Record::operator[](int num)

{

return m_rs[num];

}

/* null值判断 */

bool Record::IsNull(int num)

{

if("" == m_rs[num].c_str ())

return true;

else

return false;

}

bool Record::IsNull(string s)

{

if("" == m_rs[m_field->GetField_NO(s)].c_str())

return true;

else return false;

}

/* 主要-功能:用 value tab value 的形式 返回结果 */

string Record::GetTabText()

{

string temp;

for(unsigned int i=0 ;i<m_rs.size();i++)

{

temp+=m_rs[i];

if(i<m_rs.size ()-1)

temp+="/t";

}

return temp;

}

/*-----------------------------------------------------*/

/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */

/*

* 1 记录集合

* 2 [int ]操作 [""]操作

* 3 表结构操作

* 4 数据的插入修改

*/

RecordSet::RecordSet()

{

res = NULL;

row = NULL;

pos = 0;

}

RecordSet::RecordSet(MYSQL *hSQL)

{

res = NULL;

row = NULL;

m_Data = hSQL;

pos = 0;

}

RecordSet::~RecordSet()

{

}

/*

* 处理返回多行的查询,返回影响的行数

* 成功返回行数,失败返回-1

*/

int RecordSet::ExecuteSQL(const char *SQL)

{

if ( !mysql_real_query(m_Data,SQL,strlen(SQL)))

{

//保存查询结果

res = mysql_store_result(m_Data );

//得到记录数量

m_recordcount = (int)mysql_num_rows(res) ;

//得到字段数量

m_field_num = mysql_num_fields(res) ;

for (int x = 0 ; fd = mysql_fetch_field(res); x++)

{

m_field.m_name.push_back(fd->name);

m_field.m_type.push_back(fd->type);

}

//保存所有数据

while (row = mysql_fetch_row(res))

{

Record temp(&m_field);

for (int k = 0 ; k < m_field_num ; k++ )

{

if(row[k]==NULL||(!strlen(row[k])))

{

temp.SetData ("");

}

else

{

temp.SetData(row[k]);

}

}

//添加新记录

m_s.push_back (temp);

}

mysql_free_result(res ) ;

return m_s.size();

}

return -1;

}

/*

* 向下移动游标

* 返回移动后的游标位置

*/

long RecordSet::MoveNext()

{

return (++pos);

}

/* 移动游标 */

long RecordSet::Move(long length)

{

int l = pos + length;

if(l<0)

{

pos = 0;

return 0;

}else

{

if(l >= m_s.size())

{

pos = m_s.size()-1;

return pos;

}else

{

pos = l;

return pos;

}

}

}

/* 移动游标到开始位置 */

bool RecordSet::MoveFirst()

{

pos = 0;

return true;

}

/* 移动游标到结束位置 */

bool RecordSet::MoveLast()

{

pos = m_s.size()-1;

return true;

}

/* 获取当前游标位置 */

unsigned long RecordSet::GetCurrentPos()const

{

return pos;

}

/* 获取当前游标的对应字段数据 */

bool RecordSet::GetCurrentFieldValue(const char * sFieldName,

char *sValue)

{

strcpy(sValue,m_s[pos][sFieldName].c_str());

return true;

}

bool RecordSet::GetCurrentFieldValue(const int iFieldNum,char *sValue)

{

strcpy(sValue,m_s[pos][iFieldNum].c_str());

return true;

}

/* 获取游标的对应字段数据 */

bool RecordSet::GetFieldValue(long index,const char * sFieldName,

char *sValue)

{

strcpy(sValue,m_s[index][sFieldName].c_str());

return true;

}

bool RecordSet::GetFieldValue(long index,int iFieldNum,char *sValue)

{

strcpy(sValue,m_s[index][iFieldNum].c_str());

return true;

}

/* 是否到达游标尾部 */

bool RecordSet::IsEof()

{

return (pos == m_s.size())?true:false;

}

/*

* 得到记录数目

*/

int RecordSet::GetRecordCount()

{

return m_recordcount;

}

/*

* 得到字段数目

*/

int RecordSet::GetFieldNum()

{

return m_field_num;

}

/*

* 返回字段

*/

Field * RecordSet::GetField()

{

return &m_field;

}

/* 返回字段名 */

const char * RecordSet::GetFieldName(int iNum)

{

return m_field.m_name.at(iNum).c_str();

}

/* 返回字段类型 */

const int RecordSet::GetFieldType(char * sName)

{

int i = m_field.GetField_NO(sName);

return m_field.m_type.at(i);

}

const int RecordSet::GetFieldType(int iNum)

{

return m_field.m_type.at(iNum);

}

/*

* 返回指定序号的记录

*/

Record RecordSet::operator[](int num)

{

return m_s[num];

}

/* -------------------------------------------------- */

/* +++++++++++++++++++++++++++++++++++++++++++++++++++ */

/*

* 1 负责数据库的连接关闭

* 2 执行sql 语句(不返回结果)

* 3 处理事务

*/

DataBase::DataBase()

{

m_Data = NULL;

}

DataBase::~DataBase()

{

if(NULL != m_Data)

{

DisConnect();

}

}

/* 返回句柄 */

MYSQL * DataBase::GetMysql()

{

return m_Data;

}

/*

* 主要功能:连接数据库

* 参数说明:

* 1 host 主机ip地址或者时主机名称

* 2 user 用户名

* 3 passwd 密码

* 4 db 欲连接的数据库名称

* 5 port 端口号

* 6 uinx 嵌套字

* 7 client_flag 客户连接参数

* 返回值: 0成功 -1 失败

*/

int DataBase::Connect(string host, string user,

string passwd, string db,

unsigned int port,

unsigned long client_flag)

{

if((m_Data = mysql_init(NULL)) &&

mysql_real_connect( m_Data, host.c_str(),

user.c_str(), passwd.c_str(),

db.c_str(),port , NULL,

client_flag))

{

//选择制定的数据库失败

if ( mysql_select_db( m_Data, db.c_str () ) < 0 )

{

mysql_close( m_Data) ;

return -1 ;

}

}

else

{

//初始化mysql结构失败

mysql_close( m_Data );

return -1 ;

}

//成功

return 0;

}

/*

* 关闭数据库连接

*/

void DataBase::DisConnect( )

{

mysql_close(m_Data) ;

}

/*

* 主要功能: 执行非返回结果查询

* 参数:sql 待执行的查询语句

* 返回值; n为成功 表示受到影响的行数 -1 为执行失败

*/

int DataBase::ExecQuery(string sql)

{

if(!mysql_real_query(m_Data,sql.c_str (),(unsigned long)sql.length()) )

{

//得到受影响的行数

return (int)mysql_affected_rows(m_Data) ;

}

else

{

//执行查询失败

return -1;

}

}

/*

* 主要功能:测试mysql服务器是否存活

* 返回值:0 表示成功 -1 失败

*/

int DataBase::Ping()

{

if(!mysql_ping(m_Data))

return 0;

else

return -1;

}

/*

* 主要功能:关闭mysql 服务器

* 返回值;0成功 -1 失败

*/

int DataBase::ShutDown()

{

if(!mysql_shutdown(m_Data,SHUTDOWN_DEFAULT))

return 0;

else

return -1;

}

/*

* 主要功能:重新启动mysql 服务器

* 返回值;0表示成功 -1 表示失败

*/

int DataBase::ReBoot()

{

if(!mysql_reload(m_Data))

return 0;

else

return -1;

}

/*

* 说明:事务支持InnoDB or BDB表类型

*/

/*

* 主要功能:开始事务

*/

int DataBase::Start_Transaction()

{

if(!mysql_real_query(m_Data, "START TRANSACTION" ,

(unsigned long)strlen("START TRANSACTION") ))

{

return 0;

}

else

//执行查询失败

return -1;

}

/*

* 主要功能:提交事务

* 返回值:0 表示成功 -1 表示失败

*/

int DataBase::Commit()

{

if(!mysql_real_query( m_Data, "COMMIT",

(unsigned long)strlen("COMMIT") ) )

{

return 0;

}

else

//执行查询失败

return -1;

}

/*

* 主要功能:回滚事务

* 返回值:0 表示成功 -1 表示失败

*/

int DataBase::Rollback()

{

if(!mysql_real_query(m_Data, "ROLLBACK",

(unsigned long)strlen("ROLLBACK") ) )

return 0;

else

//执行查询失败

return -1;

}

/* 得到客户信息 */

const char * DataBase::Get_client_info()

{

return mysql_get_client_info();

}

/*主要功能:得到客户版本信息*/

const unsigned long DataBase::Get_client_version()

{

return mysql_get_client_version();

}

/* 主要功能:得到主机信息 */

const char * DataBase::Get_host_info()

{

return mysql_get_host_info(m_Data);

}

/* 主要功能:得到服务器信息 */

const char * DataBase::Get_server_info()

{

return mysql_get_server_info( m_Data );

}

/* 主要功能:得到服务器版本信息 */

const unsigned long DataBase::Get_server_version()

{

return mysql_get_server_version(m_Data);

}

/*主要功能:得到 当前连接的默认字符集*/

const char * DataBase::Get_character_set_name()

{

return mysql_character_set_name(m_Data);

}

/*

* 主要功能返回单值查询

*/

char * DataBase::ExecQueryGetSingValue(string sql)

{

MYSQL_RES * res;

MYSQL_ROW row ;

char *p = NULL;

if(!mysql_real_query( m_Data, sql.c_str(),(unsigned long)sql.length()))

{

//保存查询结果

res = mysql_store_result( m_Data ) ;

row = mysql_fetch_row( res ) ;

p = ((row[0]==NULL)||(!strlen(row[0])))?"-1":row[0];

mysql_free_result( res ) ;

}

else

//执行查询失败

p = "-1";

return p;

}

/*

* 得到系统时间

*/

const char * DataBase::GetSysTime()

{

return ExecQueryGetSingValue("select now()");

}

/*

* 主要功能:建立新数据库

* 参数:name 为新数据库的名称

* 返回:0成功 -1 失败

*/

int DataBase::Create_db(string name)

{

string temp ;

temp="CREATE DATABASE ";

temp+=name;

if(!mysql_real_query( m_Data,temp.c_str () ,

(unsigned long)temp.length ()) )

return 0;

else

//执行查询失败

return -1;

}

/*

* 主要功能:删除制定的数据库

* 参数:name 为欲删除数据库的名称

* 返回:0成功 -1 失败

*/

int DataBase::Drop_db(string name)

{

string temp ;

temp="DROP DATABASE ";

temp+=name;

if(!mysql_real_query( m_Data,temp.c_str () ,

(unsigned long)temp.length ()) )

return 0;

else

//执行查询失败

return -1;

}

/*-----------------------------------------------------*/

};

/*

* 使用例子

*/

#include "zlb_mysql.h"

using namespace std;

void main()

{

zlb_mysql::DataBase zlb;

//连接数据库

if(-1 == zlb.Connect("localhost"/*本地数据库,可以是远程 ip*/,

"root"/*用户名*/,"apple"/*密码*/,

"test"/*数据库名*/,

0,0/*两个标志,mysql文档有说明,一般为0*/))

{

std::cout<<"connect failed "<<std::endl;

}

else

{

std::cout<<"connect success"<<std::endl;

}

//通过返回的数据库句柄,建立记录急,你可以通过返回的这个句柄建立多个记录急

zlb_mysql::RecordSet rs(zlb.GetMysql());

rs.ExecuteSQL("select * from testtable");//这个语句大家都知道是什么意思了

cout<<rs.GetRecordCount()/*返回的总的记录数*/<<endl;

cout<<rs.GetFieldNum()/*返回的总的字段数*/<<endl;

cout<<rs[0].GetTabText()/*返回第一条记录,你也可以rs[1].GetTabText()

如果你有多条记录,

*/

<<endl;

/*实现遍列,也可以使用后面的遍列方式*/

for(int i=0;i<rs.GetRecordCount();++i)

{

for(int j =0;j<rs.GetFieldNum();++j)

cout<<rs[i][j];

cout<<endl;

}

zlb_mysql::Field *fd = rs.GetField();/*你可以通过这样的方式,获取字段的信息*/

cout<<fd->GetField_NO("Password")/*返回我表里的 Password 字段的位置,不

是记录的位置*/

<<endl;

cout<<rs[0]["Password"]<<endl;/*输出第0行第Password列的值*/

cout<<rs[0][fd->GetField_NO("Password")]<<endl;/*你也可以这样*/

cout<<rs.GetFieldName(0)/*获取字段的名字*/<<endl;

cout<<rs.GetFieldType("UserName")/*获取字段的类型,是mysql里定义的*/<<endl;

cout<<rs.GetCurrentPos()/*获取当前记录的位置*/<<endl;

char s[50];

rs.GetCurrentFieldValue(1,s);/*获取当前记录对应字段的值*/

cout<<s<<endl;

cout<<rs.Move(1)<<endl;/*移动游标,正数往前 负数往后*/

cout<<rs.GetCurrentPos()<<endl;

rs.GetCurrentFieldValue(1,s);

cout<<s<<endl;

rs.MoveFirst();/*移动游标到最前*/

while(!rs.IsEof()/*判断是否到达游标尾,实现遍列*/)

{

rs.GetCurrentFieldValue("UserName",s);

cout<<s<<"/t";

rs.GetCurrentFieldValue("Password",s);

cout<<s<<"/t/n";

rs.MoveNext();

}

rs.GetFieldValue(0,"UserName",s);/*获取指定行 的记录值*/

cout<<s<<"/t";

rs.GetFieldValue(0,"Password",s);

cout<<s<<"/t/n";

}

-------------

使用了一段时间后发现两处地方有问题,特添加修改如下:

1在函数int RecordSet::ExecuteSQL(const char *SQL)

{ //添加如下代码

m_field.m_name.clear();

m_field.m_type.clear();

m_recordcount = 0;

m_field_num = 0;

m_s.clear();

pos = 0;

//和以前一样

if ( !mysql_real_query(m_Data,SQL,strlen(SQL)))...........

2 函数bool RecordSet::MoveLast()

修改为:

bool RecordSet::MoveLast()

{

pos = m_s.size()-1;

if(pos <0)

pos = 0;

return true;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: