Chinaunix首页 | 论坛 | 博客
  • 博客访问: 18680250
  • 博文数量: 7460
  • 博客积分: 10434
  • 博客等级: 上将
  • 技术积分: 78178
  • 用 户 组: 普通用户
  • 注册时间: 2008-03-02 22:54
文章分类

全部博文(7460)

文章存档

2011年(1)

2009年(669)

2008年(6790)

分类: Mysql/postgreSQL

2008-04-02 15:48:01

 

用C++操作MySQL数据库类:

注释:这几个类对处理不是很大数据量的操作是很理想的, 但不适宜特大型的数据的查询,因为源码中将查询到的数据直接放入了内存。

/*
 *  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 
#include 
#include 

using namespace std;

namespace zlb_mysql{
 
 /*
  * 字段操作 
 */
 class Field
 {
 public :
  /* 字段名称 */
  vector m_name;
  /* 字段类型 */
  vector 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 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 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;iGetField_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 ;iname);
    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 "<GetField_NO("Password")/*返回我表里的 Password 字段的位置,不
                   是记录的位置*/
   <GetField_NO("Password")]<

(责任编辑;卢兆林)

阅读(502) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~