mysql clear c_c/c++连接mysql数据库

由于项目需要,要用c/c++链接mysql数据库。网上很多类似的解说,但是大部分都需要在本机器上安装完整版的msyql。其实,有时候我们并不想在改变自己电脑上原有的环境,但是我们却希望通过我们的程序链接数据库。比如:我在本机上已经安装了一个mysql,但并不是完整版的(比如appserv集成mysql或者wamp集成mysql),或者我的工作在局域网中,我只需要链接另外一台机器上的mysql。这样,为链接mysql而从头安装mysql server并不是一个最佳的选择。

mysql官网中提供了connector能够满足我们的需求。截止到目前,connector的种类有:ODBC、NET、J、Python、C++、C、PHP。由于C++包含了C,而对于我而言更习惯C的链接方式,所以,本人采用了Connector/C。官网的下载地址为:http://dev.mysql.com/downloads/connector/,但是下载需要注册,我早就忘了oracle的账号了,后来又重新注册了一下。为防止一些人遇到与我一样的问题,我上传了一些Connector for c/c++,以供大家下载使用。下载网址为:点击打开链接。

将下载的mysql-connector-c-6.1.2-win32.zip解压,重命名目录名为mysql,并将mysql文件夹剪切至vs工作目录中。本人的vs版本为2008。

有两种方式连接mysql数据库

1、动态链接:添加mysql的include目录(项目工作目录/mysql/include)到工程(右击 - 属性- 配置属性 - C/C++ - 常规- 附加包含目录),然后添加mysql的lib目录(项目工作目录/mysql/lib)到工程(右击 - 属性- 配置属性 - 连接器- 常规-附加包含目录)。这种方式为动态链接,在编译后的exe文件运行时,需要把libmysql.dll文件拷贝到exe文件的同目录中,这用起来比较麻烦。

2、如何把所有的代码都打包在一个exe中呢?那么就是静态连接。我们还可以在链接的时候用mysqlclient.lib库。具体为:首先然后改成release模式(因为mysqlclient.lib是在release模式下编译出来的),然后添加mysql的include目录(项目工作目录/mysql/include)到工程(右击 - 属性- 配置属性 - C/C++ - 常规- 附加包含目录),最后添加mysql的lib下对应的vc版本目录到工程而不是lib目录。比如:我用的是vs2008,其内部版本号为vs9,那么我将项目工作目录/mysql/lib/vs9目录添加到工程中(右击 - 属性- 配置属性 - 连接器- 常规-附加包含目录)。vs的版本号与年份的对应关系如下图所示。

1eabb9a63f3f85c0d168417cb9a1b5d0.png

一个示例代码如下:#include "mysql.h"

#include 

#pragma comment(lib, "mysqlclient.lib")

#pragma comment(linker,"/nodefaultlib:LIBCMT.lib")

#pragma comment(linker,"/nodefaultlib:MSVCRTD.lib")

int main(int argc,char **argv)

{

MYSQL* mysql = NULL;

mysql = mysql_init(mysql);

MYSQL_RES* res;

MYSQL_ROW record;

mysql_real_connect(mysql, "localhost", "root","123456", "kangry", 3306, NULL, NULL);

mysql_query(mysql, "select * from whu_user;");

res = mysql_store_result(mysql);

while((record=mysql_fetch_row(res)))

{

printf("user_id=%s,user_name=%s,user_password=%s\n", record[0], record[1], record[2]);

}

mysql_free_result(res);

mysql_close(mysql);

getchar();

return 0;

}

其中代码第四行是链接lib文件,第5、6行必须加上,表示忽略LIBCMT.lib和MSVCRTD.lib库。否则会报类似如下错误:

error LNK2005: __configthreadlocale 已经在 MSVCRT.lib(MSVCR90.dll) 中定义

若最开始未调成release模式,那么在添加mysql的lib时需要将工作目录/mysql/lib/vs9/debug目录添加到工程,并将项目的运行时库改成MT(多线程),具体为:项目邮件-》属性-》配置属性-》C/C++-》代码生成-》运行时库。否则,可能会报如下错误:warning LNK4217: 本地定义的符号 _printf 在函数 _main 中导入。

另外,我还编了一个c/c++链接mysql的数据库类,这里贴出源代码,供大家和我以后参考。

common.h#ifndef __COMMON_H

#define __COMMON_H

/************************************************************************/

/* 以下是系统的配置定义                                                 */

/************************************************************************/

#define USE_WINDOWS 1

#define CHARSETTYPE "utf8"

/************************************************************************/

/* 以下是数据库定义                                                     */

/************************************************************************/

#define DATABASE_SERVER"localhost"

#define DATABASE_USER"root"

#define DATABASE_PASS"123456"

#define DATABASE_NAME"test"

#endif

mydb.h#ifndef __MY_DB_H

#define __MY_DB_H

#include 

#include 

#include 

#include 

#include 

#include 

#include "common.h"

#if USE_WINDOWS

#pragma comment(lib, "mysqlclient.lib")

#pragma comment(linker,"/nodefaultlib:LIBCMT.lib")  //忽略LIBCMT.lib库

#pragma comment(linker,"/nodefaultlib:MSVCRTD.lib")  //忽略MSVCRTD.lib库

#endif

using namespace std;

struct RECORD{

int length;

char ** data;

};

class CMyDB

{

public:

CMyDB();

bool initDB(const string& server_host , const string& user, const string& password, const string& db_name);

void closeDB();

bool executeSQL(const string& sql_str, bool store_result=true);

void clearDB(const string& sql_str);

void clearDB();

bool truncateTable(const string& tableName);

const char* getLastError();

RECORD getNextRecord(const string& sql_str);

~CMyDB();

private:

MYSQL *connection;

map m_res;

RECORD record;

};

#endif

mydb.cpp#include "mydb.h"

CMyDB::CMyDB()

{

//初始化连接数据库变量

connection = mysql_init(NULL);

if(connection == NULL)

{

perror("mysql_init");

exit(1);

}

}

CMyDB::~CMyDB()

{

closeDB();

}

//初始化数据库 数据库连接

bool CMyDB::initDB(const string& server_host , const string& user, const string& password , const string& db_name )

{

//运用mysql_real_connect函数实现数据库的连接

connection = mysql_real_connect(connection , server_host.c_str() , user.c_str() , password.c_str() , db_name.c_str() , 0 , NULL , 0);

if(connection == NULL)

{

perror("mysql_real_connect");

exit(1);

}

//设置编码

if(mysql_query(connection, "set names " CHARSETTYPE))

{

fprintf(stderr, "%d: %s\n",mysql_errno(connection), mysql_error(connection));

exit(1);

}

return true;

}

//关闭数据库连接

void CMyDB::closeDB()

{

//关闭初始化连接数据库变量

clearDB();

if(connection != NULL){

mysql_close(connection);

connection=NULL;

}

}

void CMyDB::clearDB(const string& sql_str){

if (m_res[sql_str])

{

mysql_free_result(m_res[sql_str]);

m_res.erase(sql_str);

}

}

void CMyDB::clearDB(){

for (map::iterator iter=m_res.begin();iter!=m_res.end();iter++)

{

mysql_free_result(iter->second);

}

m_res.clear();

}

//执行SQL语句

bool CMyDB::executeSQL(const string& sql_str,bool store_result/*=true*/)

{

int t = mysql_query(connection,  sql_str.c_str());

if(t){

printf("Error making query: %s\n" , mysql_error(connection));

exit(1);

}else if(store_result){

if (m_res[sql_str]){

mysql_free_result(m_res[sql_str]);

}

//初始化逐行的结果集检索

m_res[sql_str] = mysql_store_result(connection);

}

return true;

}

//获得下一行的数据

RECORD CMyDB::getNextRecord(const string& sql_str){

record.data=mysql_fetch_row(m_res[sql_str]);

record.length=mysql_num_fields(m_res[sql_str]);

return record;

}

//表的清空

bool CMyDB::truncateTable(const string& tableName)

{

string sql="truncate table ";

sql+=tableName;

if(mysql_query(connection , sql.c_str()))

{

printf("Error making query: %s\n" , mysql_error(connection));

exit(1);

}

return true;

}

//获得最近的错误

const char* CMyDB::getLastError(){

return mysql_error(connection);

}

main.cpp#include "common.h"

#include "mydb.h"

#include 

#include 

using namespace std;

int main(int argc,char **argv)

{

CMyDB mydb;

mydb.initDB(DATABASE_SERVER,DATABASE_USER,DATABASE_PASS,DATABASE_NAME);

string s_sql="select * from user limit 10";

mydb.executeSQL(s_sql);

RECORD record=mydb.getNextRecord(s_sql);

while (record.data)

{

for (int i=0;i

{

printf("%s\t",record.data[i]);

}

printf("\n");

record=mydb.getNextRecord(s_sql);

}

mydb.clearDB(s_sql);

mydb.closeDB();

return 0;

}

希望我的随笔能给大家带来帮助。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值