`

VC++操作mysql的完整配置流程

 
阅读更多

一直以来都想用C/C++来操作Mysql数据库,应用C++的高效率和严密的语法,我窍以为处理效果会更好。因为一直用php的时候,总觉得格式是简单,但不够严密,有时会出现一些意想不到的结果,可能也只是我对php理解肤浅或偏见吧。
   C++操作数据库肯定是可以的,但好像有点麻烦。直接使用VC的添加数据库向导,但各种途径都找不到Mysql的驱动程序,只能告罢。在网上找了很多资料,有建立数据库连接池的,有建立数据操作的实例或者完整的类,但对于环境配置的,或者说是指导怎样建立数据库连接,都语焉不详,若照着一步步进行操作,最终总是错误,所以我只能探索着来了。
   经过一整天的探索,终于可以成功“执行”了,顺利进行连接和各种操作,如create、insert into、select、fetch_row等。下面将这整个配置过程,记录下来,以供有兴趣者参考,这里使用的是Mysql提供的C API进行的。
   一、当然是要安装mysql服务器,在安装过程有一步选择安装组件的,请把Developer components(开发组件)选上,这样安装之后才有include文件夹及里面的C头文件,而这些文件在下面操作将会用到。当然也可以不安装开发组件,但下面操作涉及的包含文件,就必须从其他途径得到。
   二、把libmysql.dll复制到操作系统的system目录下(如c:\windows\system32)。libmysql.dll一般在Mysql安装后文件夹的/lib/debug/目录下。但需要提醒一下,(一)提到的安装开发组件并非必要,但如果不安装会出现一个小问题。因为安不安装开发组件,最后得到libmysql.dll不一样的,如我自己的系统不安装开发组件时的libmysql.dll大小是1496k,而安装了却是1968k。而且使用不安装开发组件时的libmysql.dll时,在其他条件配置完成情况下程序也能编译执行,基本操作也能达到预期效果,只是执行后会出现这样的错误提示"Error in my_thread_global_end();3 threads didn't exit",其中的道理我不慎明了,但知道出错了。
   三、要使用Mysql提供的API就必须包含mysql.h(#include "mysql.h" ),当然如果只是简单加入这个语句,编译时肯定提示找不到文件mysql.h的错误。按照网上给的做法,把“\mysql\include”添加到编译选项的包含路径中(如我的安装路径是“C:\Program Files\MySQL\MySQL Server 5.0”,则在Project Options中加入 /I "C:\Program Files\MySQL\MySQL Server 5.0\include\")。但我这样操作了,还是出现找不到文件的错误提示,至今不知为何。所以在这里提供另外两种我尝试可行的办法。(1)在文件包含时提供路径,如我使用#include "C:\Program Files\MySQL\MySQL Server 5.0\include\mysql.h"来包含头文件。(2)把头文件复制到VC的头文件库里(如C:\Program Files\Microsoft Visual Studio\VC98\Include),不能只复制一个mysql.h文件,因为mysql.h也包含其他文件,经过实际探索,必须复制一下六个文件:mysql.h my_alloc.h my_list.h mysql_com.h mysql_time.h mysql_version.h typelib.h,然后就可以直接#include "mysql.h"。到这里程序可以编译通过了,即Compile main.cpp通过。
   但组建可执行程序(Build main.exe)就出错了,有诸多Error,提示类似"main.obj : error LNK2001: unresolved external symbol _mysql_num_fields@4",这是库文件链接失败,下一步操作就解决这个问题。
   四、在mysql安装的/lib/debug/目录下可以找到libmysql.lib这个文件,这就是我们需要的文件。在网上搜索一下,lib文件一般是函数定义编译后的库文件,也就是程序中的使用mysql_num_fields、mysql_num_rows等操作数据库的函数的定义了。所以必须使程序链接时找到这个文件,类似于(三),方法有两种:(1) 在VC的Project->Setings对话框的link选项卡最下面的Project Options文本框加入"C:\Program Files\MySQL\MySQL Server 5.0\lib\debug\libmysql.lib"。(2)把libmysql.lib复制进VC的库文件里(如复制进这个目录C:\Program Files\Microsoft Visual Studio\VC98\Lib),然后在(1)中提到的Project Options中只要加入libmysql.lib就行。
   经过以上的配置之后就可以使用C++链接mysql数据库了,而且可以使用mysql提供的C API进行数据库程序的开发。下面对几个基本函数进行简单说明(参考网文稍加修改),详细说明请看mysql文档:
---- 1. MYSQL *mysql_init(MYSQL *mysql)
---- 初始化一个类型为MYSQL的数据结构,为执行mysql_real_connect()做准备。参数
mysql为指向该结构的指针,如果mysql为NULL,则新建并初始化一个MYSQL的数据结构。
新建的结构将在mysql_close()中释放。
---- 若成功,返回初始化的MYSQL数据结构的指针,否则返回NULL。
---- 2. MYSQL *mysql_real_connect(MYSQL *mysqlStruct, const char *host,
---- const char *user, const char *passwd, const char *db,
---- unsigned int port, const char *unix_socket, unsigned int client_flag)
---- 与MySQL数据库引擎建立连接。在执行进一步的数据操作之前,必须保证mysql_real_connect()成功返回。
---- 参数mysqlStruct是mysql_init()的返回值;
---- 参数host是运行MySQL数据库引擎的机器的TCP/IP主机名,如为NULL则默认为"localhost";
---- 参数user和passwd是MySQL数据库的合法用户和口令;
---- 参数db是连接的数据库名;
---- 参数port,unix_socket和client_flag一般取默认值。如果端口不是mysql默认的3306,就必须指明。
---- 3. int mysql_query(MYSQL *mysql, const char *query)
---- 执行query字符串中的SQL语句,query必须以\0结尾。如果成功,返回0。
---- 4. MYSQL_RES *mysql_store_result(MYSQL *mysql)
---- 返回SELECT,SHOW,DESCRIBE, EXPLAIN等语句执行的结果。函数新建一个MYSQL_
RES的数据结构,把结果存储在该结构中。如果查询没有匹配的结果,则返回空数据集。
处理完结果集后,必须调用mysql_free_result()。
---- 如果出错,返回NULL,否则返回MYSQL_RES结构的指针。
---- 5. MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
---- 取回结果集中的下一条记录,如果没有记录或出错,返回NULL。一条记录中的字段
数可以用mysql_num_fields(result)获得,各字段的值可以用row[0] 到 row[mysql_nu
m_fields(result)-1]的数组来访问。
   下面提供一个示例程序,以供参考,只要新建win32 console Aplication工程,新建C++ Source File,然后复制进去,进行如上面所述的各项环境配置就能执行:

#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "mysql.h"

void ErrLog(const char *str){
printf("%s",str);
}
int main( int argc, char * argv[] )
{
   //数据库名
   char szTargetDSN[] = "DBname";
   //Sql语句
   char szSqlText[500]="";
   char aszFlds[ 25 ][ 25 ];
   //连接数据库的合法用户名
   const char username[] = "root";
   //密码
   const char password[] = "root_password";
   //链接端口,默认为3306
   unsigned int port = 3306;
   MYSQL* myData ;
   MYSQL_RES * res ;
   MYSQL_FIELD * fd ;
   MYSQL_ROW row ;
   int i,j,k;
   BOOL bCreate = TRUE;
   if ( (myData = mysql_init((MYSQL*) 0)) && mysql_real_connect( myData, NULL, username, password, szTargetDSN, port, NULL, 0 ) )
   {
    /*sprintf(szSqlText,"SET NAMES 'gb2312' ");
    //sprintf(szSqlText,"insert into yygtext (id,yygtext) values(2,'这是测试用的')");

    if(mysql_query(myData,szSqlText)){
     ErrLog("set character false");
    } */
    //table_name为数据表,运行本程序必须在'DBname'库存在'table_table',可根据实际情况进行设置。
    sprintf(szSqlText,"select * from table_name limit 0,12 ");
    if(mysql_query(myData,szSqlText)){
     mysql_close(myData);
     printf("select failed.\n");
     return false;
    }else{
     res = mysql_store_result(myData);
     i = (int)mysql_num_rows(res);
     printf( "Query: %s\n%ld records found: \n", szSqlText, i ) ;
     for(i=0;fd=mysql_fetch_field(res);i++){
      strcpy(aszFlds[i],fd->name);
     }
     for(i=1;row=mysql_fetch_row(res);){
      j = mysql_num_fields(res);
      for(k=0;k<j;k++){
       printf("%s:\t%s\n",aszFlds[k],row[k]);
      }
      printf("--------------------------------------\n");
     }
     mysql_free_result(res);
    }
   }else{
    ErrLog("\n connect DB failed. ");
    mysql_close( myData ) ;
       return false ;
   }
   mysql_close( myData ) ;
   return true ;
}

 

转自:http://hi.baidu.com/yygspace/blog/item/7e597851d351d310367abef0.html

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics