C++连接MySQL(二):自制一个通用的MySQL类

阅读本文之前建议你先看下面这篇作为基础

C++连接MySQL(一):环境配置和实例 http://blog.csdn.net/zh405123507/article/details/6795742


有了MySQL API的支持,C++是连上数据库了,可是每次都去查API函数表,总是比较麻烦的……为了体现“代码重用”思想,你可以为自己做一个调用MySQL的类,把繁琐的操作封装成简单的函数,为今后使用做准备。


常用的函数

初始化API库:mysql_library_init() 

初始化数据结构:mysql_init()

连接数据库前的选项:mysql_options()

错误信息:mysql_error()

连接函数:mysql_real_connect()

执行SQL语句:mysql_query()

转存查询结果:mysql_store_result()

关闭连接:mysql_close()


示例代码

dbctrl.h

#ifndef __DBCTRL_H__
#define __DBCTRL_H__

#include "winsock.h"
#include "iostream.h"
#include <string>
#include "mysql.h"
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libmysql.lib")
using namespace std;

class DBctrl
{
	private:
		MYSQL mydata;                      //MySQL对象,必备的一个数据结构
		MYSQL_RES *result;                 //用于存放结果 建议用char* 数组将此结果转存
	public:
		int   row;                         //查询结果的行数
		int   field;                       //查询结果的列数
		int   autoNum;                     //上一次auto_increment的值
		int   errorNum;                    //错误代号
		const char* errorInfo;             //错误提示
		int   affectedRow;                 //上一次查询影响的行数
		

		DBctrl();                          //构造函数

		void DBtest(int flag);            
		void DBerror();
		void DBconn(char* server, char* username, char* password, char* database,int port);
		void DBquery(string queryStr);
		void DBquery(string queryStr, char* data[100][100]);
		void DBclose();
};

#endif

dbctrl.cpp

#include "dbctrl.h"

//构造函数 初始化各个变量和数据
DBctrl::DBctrl()
{
	mysql_library_init(0,NULL,NULL);
	mysql_init(&mydata);
	mysql_options(&mydata,MYSQL_SET_CHARSET_NAME,"gbk");

	row=0;
	field=0;
	autoNum=0;
	errorNum=0;
	errorInfo="ok";
	affectedRow=0;
}

//编译时显示测试信息,正式使用时把此函数主题注释掉即可
void DBctrl::DBtest(int flag)
{
	char* message;
	switch (flag)
	{
		case 1:
			message="Database OK!";
			break;
		case 2:
			message="Database error!";
			break;
		case 3:
			message="Query OK!";
			break;
		case 4:
			message="Query error!";
			break;
		case 5:
			message="data overflew!";
			break;
		default:
			message=NULL;
			break;
	}
	if (message!=NULL) cout<<message<<endl;
}

//收集错误信息
void DBctrl::DBerror()
{
	errorNum=mysql_errno(&mydata);
	errorInfo=mysql_error(&mydata);
}

//连接数据库
void DBctrl::DBconn(char* server, char* username, char* password, char* database,int port)
{
	char* svr=server;    //server:服务器域名或IP
	char* usr=username;  //username:数据库用户名
	char* pwd=password;  //password:数据库密码
	char* dbn=database;  //database:数据库名
	int   prt=port;      //port:端口号

	//这里新建变量并再赋一次值是为了调试的时候显示连接参数,其实可以不这么做
	if(mysql_real_connect(&mydata,svr,usr,pwd,dbn,prt,0,0) != NULL)
		DBtest(1);
	else
		DBtest(2);
}

//执行查询语句
void DBctrl::DBquery(string queryStr)
{
	if(0==mysql_query(&mydata,queryStr.c_str()))
		DBtest(3);
	else
		DBtest(4);
	DBerror();
}

//执行查询语句(重载,有返回结果的)
void DBctrl::DBquery(string queryStr, char* data[100][100])
{
	if(0==mysql_query(&mydata,queryStr.c_str()))
		DBtest(3);
	else
		DBtest(4);

	affectedRow=mysql_affected_rows(&mydata);
	autoNum=mysql_insert_id(&mydata);
	result=mysql_store_result(&mydata);

	row=mysql_num_rows(result);//计算行数
	field=mysql_num_fields(result);//计算列数

	//转出数据
	if(row>100 || field>100)
		DBtest(5);
	else
	{
		MYSQL_ROW line=NULL;
		line=mysql_fetch_row(result);//取第一行结果

		int j=0;
		while(NULL!=line)//查看是否为空行,是则结束,否则将这一行的数据转存到data的一行中并取下一行
		{	
			for(int i=0; i<field;i++)
			{
				data[j][i]=line[i];
			}
			j++;
			line=mysql_fetch_row(result);
		}
	}

	DBerror();
}

//断开连接
void DBctrl::DBclose()
{
	mysql_close(&mydata);
}

主函数

#include "dbctrl.h"

void main()
{
	DBctrl my;              //刚才建的通用类
	string query;           //存放查询语句
	char*  data[100][100];  //存放查询结果

	query="Select * from table1";
	my.DBconn("localhost","root","123456","test",3306);
	my.DBquery(query,data); //执行query中的语句,并将结果回送给data
	my.DBclose();           //关闭连接

	/* 此处用for循环显示data数组的内容... */
}



常见的问题

1、编译时出现unsolved extrenal symbol之类的提示

请将类里的函数声明(函数头部)和函数定义(函数主体)分到两个文件中,如上面的dbctrl.h和dbctrl.cpp。

编译时,在主函数之前加上#include "dbctrl.h",在工程中加入dbctrl.cpp。


2、连接不上数据库

主机名、用户名、密码、数据库、端口都必须正确。并且此用户的权限最好设置成可以远程连接数据库。

在MySQL控制台输入命令:update user set host = '%' where user = 'root',可使root账户能在任意主机登录本数据库。

为了安全起见,还是为目标数据库新建一个账户并分配好权限,这里不赘述。


3、“MySQL server has gone away”

说明连接自动断开了,需要检查两件事:

(1)是不是真的连上数据库了

(2)如果程序结束前忘记使用mysql_close()来关闭连接可能导致连接数过多


更多问题,会继续补充……


MySQL C API 函数概述

函数

描述

mysql_affected_rows()

返回上次UPDATEDELETEINSERT查询更改/删除/插入的行数。

mysql_autocommit()

切换 autocommit模式,ON/OFF

mysql_change_user()

更改打开连接上的用户和数据库。

mysql_charset_name()

返回用于连接的默认字符集的名称。

mysql_close()

关闭服务器连接。

mysql_commit()

提交事务。

mysql_connect()

连接到MySQL服务器。该函数已不再被重视,使用mysql_real_connect()取代。

mysql_create_db()

创建数据库。该函数已不再被重视,使用SQL语句CREATE DATABASE取而代之。

mysql_data_seek()

在查询结果集中查找属性行编号。

mysql_debug()

用给定的字符串执行DBUG_PUSH

mysql_drop_db()

撤销数据库。该函数已不再被重视,使用SQL语句DROP DATABASE取而代之。

mysql_dump_debug_info()

让服务器将调试信息写入日志。

mysql_eof()

确定是否读取了结果集的最后一行。该函数已不再被重视,可以使用mysql_errno()mysql_error()取而代之。

mysql_errno()

返回上次调用的MySQL函数的错误编号。

mysql_error()

返回上次调用的MySQL函数的错误消息。

mysql_escape_string()

为了用在SQL语句中,对特殊字符进行转义处理。

mysql_fetch_field()

返回下一个表字段的类型。

mysql_fetch_field_direct()

给定字段编号,返回表字段的类型。

mysql_fetch_fields()

返回所有字段结构的数组。

mysql_fetch_lengths()

返回当前行中所有列的长度。

mysql_fetch_row()

从结果集中获取下一行

mysql_field_seek()

将列光标置于指定的列。

mysql_field_count()

返回上次执行语句的结果列的数目。

mysql_field_tell()

返回上次mysql_fetch_field()所使用字段光标的位置。

mysql_free_result()

释放结果集使用的内存。

mysql_get_client_info()

以字符串形式返回客户端版本信息。

mysql_get_client_version()

以整数形式返回客户端版本信息。

mysql_get_host_info()

返回描述连接的字符串。

mysql_get_server_version()

以整数形式返回服务器的版本号。

mysql_get_proto_info()

返回连接所使用的协议版本。

mysql_get_server_info()

返回服务器的版本号。

mysql_info()

返回关于最近所执行查询的信息。

mysql_init()

获取或初始化MYSQL结构。

mysql_insert_id()

返回上一个查询为AUTO_INCREMENT列生成的ID

mysql_kill()

杀死给定的线程。

mysql_library_end()

最终确定MySQL C API库。

mysql_library_init()

初始化MySQL C API库。

mysql_list_dbs()

返回与简单正则表达式匹配的数据库名称。

mysql_list_fields()

返回与简单正则表达式匹配的字段名称。

mysql_list_processes()

返回当前服务器线程的列表。

mysql_list_tables()

返回与简单正则表达式匹配的表名。

mysql_more_results()

检查是否还存在其他结果。

mysql_next_result()

在多语句执行过程中返回/初始化下一个结果。

mysql_num_fields()

返回结果集中的列数。

mysql_num_rows()

返回结果集中的行数。

mysql_options()

mysql_connect()设置连接选项。

mysql_ping()

检查与服务器的连接是否工作,如有必要重新连接。

mysql_query()

执行指定为“以Null终结的字符串”的SQL查询。

mysql_real_connect()

连接到MySQL服务器。

mysql_real_escape_string()

考虑到连接的当前字符集,为了在SQL语句中使用,对字符串中的特殊字符进行转义处理。

mysql_real_query()

执行指定为计数字符串的SQL查询。

mysql_refresh()

刷新或复位表和高速缓冲。

mysql_reload()

通知服务器再次加载授权表。

mysql_rollback()

回滚事务。

mysql_row_seek()

使用从mysql_row_tell()返回的值,查找结果集中的行偏移。

mysql_row_tell()

返回行光标位置。

mysql_select_db()

选择数据库。

mysql_server_end()

最终确定嵌入式服务器库。

mysql_server_init()

初始化嵌入式服务器库。

mysql_set_server_option()

为连接设置选项(如多语句)。

mysql_sqlstate()

返回关于上一个错误的SQLSTATE错误代码。

mysql_shutdown()

关闭数据库服务器。

mysql_stat()

以字符串形式返回服务器状态。

mysql_store_result()

检索完整的结果集至客户端。

mysql_thread_id()

返回当前线程ID

mysql_thread_safe()

如果客户端已编译为线程安全的,返回1

mysql_use_result()

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

mysql_warning_count()

返回上一个SQL语句的告警数。



相关文章

C++连接MySQL(一):环境配置和实例 http://blog.csdn.net/zh405123507/article/details/6795742

远程访问MySql数据库的方法 http://blog.csdn.net/jetcui1/article/details/1724574

MySQL权限分配 http://www.cnblogs.com/yangy608/archive/2011/01/22/1942099.html


  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

姜庄湖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值