数据库MYSQL入门教程(4)——VS开发环境配置

数据库 waitig 490℃ 百度已收录 0评论

笔者用的是VS2017,系统版本64为win10家庭中文版,64位的MYSQL5.6.38。

第一步:新建WIN32控制台项目,生成后,右键解决方案——属性

第二步:C/C++——常规——附加包含目录——编辑

第三步:添加mysql安装目录下include文件夹的路径,确定

第四步:链接器——常规——附加库包含目录——编辑

第五步:添加mysql安装目录下lib文件夹的路径,确定

第六步:链接器——附录——附加依赖项——编辑

第七步:添加libmysql.lib,确定

第八步:修改调试环境为X64

第九步:复制mysql安装路径下lib文件夹内的libmysql.lib到debug路径下

现在,各位就可以测试用C API连接MYSQL了。

以下是测试代码:

#define HAVE_STRUCT_TIMESPEC									//解决my_global.h中timespec重复定义的问题
#include <iostream>
#include <cstdlib>												//为了使用system函数
#include <my_global.h>											//包含基础库如stdio.h,如果在win下编程最好包括了,虽然会出一些问题,比如需要预定义HAVE_STRUCT_TIMESPEC
#include <my_sys.h>												//包含可移植的宏和定义,好像删除了也没大碍
#include <mysql.h>												//各类mysql操作所需要的库

using namespace std;

static void print_error(MYSQL *temp, char *message);			//汇报出错详情
void process_statement(MYSQL *conn, char *stmt_str);			//一种通用的指令输入模式
void process_result_set(MYSQL *conn, MYSQL_RES *res_set);		//结果集返回函数
void print_dashes(MYSQL_RES *res_set);							//画出指定格式的函数
int main(int argc,char *argv[]) {
	my_init();													//一些初始化工作
	static char *opt_host_name = NULL;						//服务器主机
	static char *opt_user_name = NULL;						//用户名
	static char *opt_password = "NULL;						//密码
	static unsigned int opt_port_num = 0;						//不指定连接端口,即连接默认端口
	static char *opt_socket_name = NULL;						//套接字名(此处使用内建值)
	static char *opt_db_name = "test";							//连接的数据库名
	static unsigned int opt_flags = 0;
																//MYSQL 是一个包含连接信息的结构
	static MYSQL *conn;											//连接处理器指针
	if (mysql_library_init(0, NULL, NULL)) {					//初始化客户端开发库
		print_error(conn, "wow, some errors happened");
		system("pause");
		exit(1);												//系统级别的结束进程
	}

	conn = mysql_init(NULL);									//初始化连接处理器,当参数为NULL会自动生成一个MYSQL结构并初始化,然后返回一个指向它的指针
	if (conn==NULL) {							 				//若内存不足则会返回NULL
		print_error(conn, "mysql_init() failed\
						 (probably out of memory)");
		system("pause");
		exit(1);
	}

	//在连接数据库之前,设置额外的连接选项  
	//可以设置的选项很多,这里设置字符集,否则无法处理中文  
	//必须在mysql_init()之后,mysql_real_connect()之前调用该函数。
	if (mysql_options(conn, MYSQL_SET_CHARSET_NAME, "gbk")) {
		print_error(conn, "wow, some errors happened");
		system("pause");
		exit(1);
	}

	if (mysql_real_connect(conn, opt_host_name, opt_user_name, 
		opt_password, opt_db_name, opt_port_num,
		opt_socket_name, opt_flags)==NULL)						//连接数据库,如果连接失败则返回NULL 
	{
		print_error(conn, "mysql_real_connect() failed");
		system("pause");
		exit(1);
	}
	char* sqlstr;												//sql字符串

	sqlstr = "CREATE TABLE IF NOT EXISTS user_info\
				(user_id INT UNSIGNED NOT NULL AUTO_INCREMENT,\
				PRIMARY KEY (user_id),name varchar(20) null);";
	process_statement(conn, sqlstr);							//创建一个表  
	
	sqlstr ="INSERT INTO user_info VALUES (null,'yuyuefan'),\
				(null,'chenyuting'),(null,'baby');";
	process_statement(conn, sqlstr);							//插入一些值

	sqlstr = "SELECT user_id,name FROM user_info;";
	process_statement(conn, sqlstr);							//显示刚才插入的数据  

	sqlstr = "DROP TABLE user_info;";
	process_statement(conn, sqlstr);							//删除刚才建的表 

	mysql_close(conn);											//终止连接。在使用mysql_init(NULL)的情况下,此处可不写参数。
	mysql_library_end();										//做一些必要的清理工作
	mysql_server_end();
	system("pause");
	exit(0);
}
static void print_error(MYSQL *temp, char *message)				//错误报告函数
{
	fprintf(stderr, "%s\n", message);
	if (temp != NULL)
		fprintf(stderr, "Error %u (%s):%s\n", mysql_errno(temp),
			mysql_sqlstate(temp), mysql_error(temp));
}

void process_result_set(MYSQL *conn, MYSQL_RES *res_set)		//返回结果集函数
{
	MYSQL_ROW	row	   = NULL;									//MYSQL_ROW是指针类型,所以变量为row,而非*row	
	MYSQL_FIELD *field = NULL;
	unsigned long col_len;
	
	if (mysql_errno(conn))										//错误报告
		print_error(conn, "mysql_fetch_row() failed");
	else
		printf("Number of rows returned: %lu\n",
		(unsigned long)mysql_num_rows(res_set));				//mysql_num_rows()可以返回检索到的行数,强制转UNSIGNED LONG保持其可移植性
	
	mysql_field_seek(res_set, 0);								//mysql_field_seek()用来定位到第一个结构处
	for (unsigned int i = 0; i < mysql_num_fields(res_set); i++)//遍历每一列,获取列最大值,mysql_num_fields()可获取返回数据表的列数
	{
		field = mysql_fetch_field(res_set);						//返回指向下一列的指针
		col_len = strlen(field->name);							//获取每一列文字的长度
		col_len = (col_len < field->max_length) ? field->max_length : col_len;
		col_len = (col_len < 4 && !IS_NOT_NULL(field->flags)) ? 4 : col_len;
		field->max_length = col_len;							//重置列信息
	}
	print_dashes(res_set);										//固定格式
	fputc('|', stdout);											//固定格式
	mysql_field_seek(res_set, 0);								//校准位置
	
	for (unsigned int i = 0;									//取得并打印各字段的名称 
		i < mysql_num_fields(res_set); i++)						//mysql_num_fields()可获取返回数据表的列数
	{
		field = mysql_fetch_field(res_set);
		printf(" %-*s |", (int)field->max_length, 
			field->name);										//%-*s 代表输入一个字符串,-号代表左对齐、后补空白,*号代表对齐宽度由输入时确定
	}
	fputc('\n', stdout);
	print_dashes(res_set);										//固定格式

	while ((row = mysql_fetch_row(res_set)) != NULL)			//调用mysql_fetch_row()可以依次取回结果集中的每一行,有值返回MYSQL_ROW(指针,指向各列值),没值返回NULL
	{
		mysql_field_seek(res_set, 0);
		fputc('|', stdout);										//固定格式
		for(unsigned int i=0;i< mysql_num_fields(res_set);i++)
		{
			field = mysql_fetch_field(res_set);
			printf(" %-*s |", (int)field->max_length,			//这里的每一项内容都是字符串形式
				row[i] != NULL ? row[i]: "NULL");				//每一列上有值就显示,没有就显示NULL
		}
		fputc('\n', stdout);
	}
	print_dashes(res_set);										//固定格式
}

void process_statement(MYSQL *conn, char *stmt_str)
{
	MYSQL_RES *res_set;											//为了获取结果集
	if (mysql_query(conn, stmt_str))							//发送指令,如果失败,报错问题,mysql_query是一个简单的调用函数,但是有较多的限制,比较传递的语句结尾是NULL
	{
		print_error(conn, "could not execute statement");
		system("pause");
		return;
	}
	res_set = mysql_store_result(conn);							//获取结果集
	if (res_set)												//有结果集返回时
	{
		process_result_set(conn, res_set);						//返回结果集
		mysql_free_result(res_set);								//释放占用的内存资源,如果处理完结果集不调用这句话,内存泄漏会导致程序越来越慢。
	}
	else														//无结果集返回时,判断是否有错误产生
	{
		if (mysql_field_count(conn) == 0)						//输入的语句不产生结果集
		{
			printf("Number of rows affected: %lu\n", 
				(unsigned long)mysql_affected_rows(conn));
		}
		else
		{
			print_error(conn, "Could not retrieve result set");	//出现问题
		}
	}
}

void print_dashes(MYSQL_RES *res_set)							//画出指定格式的函数
{
	MYSQL_FIELD *field;
	mysql_field_seek(res_set, 0);								//mysql_field_seek()用来定位到第一个结构处
	fputc('+', stdout);
	for (unsigned int i = 0; i < mysql_num_fields(res_set); i++)//mysql_num_fields()可获取返回数据表的列数
	{
		field = mysql_fetch_field(res_set);						// mysql_fetch_field()用来返回后序列结构的指针
		for (unsigned int j = 0; j < field->max_length + 2; j++)
			fputc('-', stdout);
		fputc('+', stdout);
	}
	fputc('\n', stdout);
}


本文由【waitig】发表在等英博客
本文固定链接:数据库MYSQL入门教程(4)——VS开发环境配置
欢迎关注本站官方公众号,每日都有干货分享!
等英博客官方公众号
点赞 (0)分享 (0)