数据库学习1 MySQL API使用

一、连接数据库

连接步骤:(每一步都是一个函数就可以解决)

1.分配或得到一个初始化的句柄

函数原型:MYSQL *mysql_init(MYSQL *mysql)

参数MYSQL *mysql:可以自己填一个,也可以填NULL。如果填NULL,则自动分配一个句柄。

返回值:初始化好的MYSQL句柄,如果错误,返回NULL;

2.与运行在主机上的MySQL数据库引擎建立连接

函数原型:

MYSQL *mysql_real_connect(
MYSQL *mysql, 
const char *host, 
const char *user, 
const char *passwd, c
onst char *db, 
unsigned int port, 
const char *unix_socket, 
unsigned long client_flag
) 

参数MYSQL *mysql就是初始化的句柄

参数const char *host是主机名或IP地址,如果“host”是NULL或字符串"localhost",连接将被视为与本地主机的连接,ip地址为127.0.0.1是与本机相连。

参数const char *user是MySQL登录ID,就是在终端进入MySQL时输入的''mysql -uroot -p'中-u后面的参数

参数const char *passwd是用户的密码

参数const char *db是用户下数据库的名称

参数unsigned int port是连接端口号,一般取0就是默认端口,不同的数据库默认端口不一样mysql默认端口是3306,Oracle默认端口是1521,mongodb 默认端口是27017。

参数const char *unix_socket描述了应使用的套接字或命名管道,一般取NULL

参数unsigned long client_flag,标志位,一般取0,有需要查资料。

3.解除句柄

函数原型:void mysql_close(MYSQL *mysql)

 

举例如下:

#include <iostream>
#include "mysql.h"

int main()
{
	MYSQL * mysql=mysql_init(NULL);//初始化
	if (mysql==NULL)
	{
		std::cout<<"init fail!\n";
		return 0;
	}
	mysql=mysql_real_connect(mysql, "127.0.0.1", "root", "160210", "scott", 0, NULL, 0);//连接数据库
	if (mysql==NULL)
	{
		std::cout<<"connect fail!\n";
		return 0;
	}
	std::cout<<"hello mysql!\n";
	mysql_close(mysql);//解除连接
	return 0;
}

 

二、更改数据库中表的内容

只是更改数据库中数据,但不显示,可以使用mysql_query函数

函数原型:int mysql_query(MYSQL *mysql, const char *query)

我的理解是将SQL语句通过字符串的方式传递给数据库,然后数据库自己解析成SQL语句,这个函数就是负责传递语句的。

参数MYSQL *mysql:初始化得到的句柄

参数const char *query:存放的是SQL语句,但是是字符串格式的,其中结尾不需要加分号

如果执行成功,返回0。如果出现错误,返回非0值。

以插入数据为例

#include <iostream>
#include "mysql.h"

int main()
{
	MYSQL * mysql=mysql_init(NULL);
	if (mysql==NULL)
	{
		std::cout<<"init fail!\n";
		return 0;
	}
	mysql=mysql_real_connect(mysql, "127.0.0.1", "root", "160210", "scott", 0, NULL, 0);
	if (mysql==NULL)
	{
		std::cout<<"connect fail!\n";
		return 0;
	}
	char query[]="insert into dept values(50, '50name', '50loc')";//将SQL命令放入字符串指针中
	if (mysql_query(mysql, query)!=0)//使用这个函数
	{
		std::cout<<"query fail!\n";
		return 0;
	}
	mysql_close(mysql);
	return 0;
}

三、显示数据库中的内容

除了需要使用mysql_query函数将SQL命令传输给数据库,另外还需要使用mysql_store_result函数得到从数据库传来的结果集,并且需要用mysql_fetch_row函数一行行地取出结果集中的内容。另外每一列的名称需要用额外的函数去取。介绍一下使用的函数

1.MYSQL_RES *mysql_store_result(MYSQL *mysql)

该函数返回一个MYSQL_RES结构体,我们将它称之为结果集,对于成功检索了数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN、CHECK TABLE等),都需要用这个函数取到结果集,并通过结果集在程序中显示出来。

参数MYSQL *mysql,就是你在哪个句柄下使用了查询语句,就是哪个句柄

返回的是结果集。

2.MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)

该函数是取出结果集中的一行,这一行是肯定还未取出的,每次取完一行,下次取就会自动取下一行,这叫游标。

返回值MYSQL_ROW其实是一个char **类型的指针,其实就是把表格中的一行的每列都变成一个字符串。然后构成的数组就是MYSQL_ROW类型。返回的MYSQL_ROW是检索结果集的下一行,也就是表的第一行是检索不到的,所以表头需要额外函数进行检索。

3.MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)

该函数是取出表头,也就是每一列的列名。

返回值是一个结构体,结构体中有一个name成员变量存放的就是列名,并且和MYSQL_ROW类似,也是每一个列使用一个结构体,所以返回的是一个结构体数组的指针。

4.my_ulonglong mysql_num_rows(MYSQL_RES *result)

返回的是结果集中的列数,也就是表的列数

5.void mysql_free_result(MYSQL_RES *result)

释放结果集。

#include <iostream>
#include "mysql.h"

void show_result(MYSQL_RES * result)
{
	unsigned int result_col=mysql_num_fields(result);//得到表中列数
	MYSQL_FIELD * fields=mysql_fetch_fields(result);//得到表头
	for (int i=0; i<result_col; i++)
	{
		std::cout<<fields[i].name<<"\t";//将表头显示出来,由于表头不太可能为NULL,所以这里没有加判断。
	}
	std::cout<<std::endl;
	MYSQL_ROW row;//用来存放表中的一行数据
	while ((row=mysql_fetch_row(result)))每次循环取一行数据
		{
			for (int i=0; i<result_col; i++)
			{
				if (row[i]==NULL)//该判断是因为表中有的值为NULL,而cout的对象是NULL时就会停止输出,退出程序。所以先要判断一下是否为NULL,NULL需要手动输出。
					std::cout<<"NULL"<<"\t";
				else std::cout<<row[i]<<"\t";
			}
			std::cout<<std::endl;
		}
}

int main()
{
	MYSQL * mysql=mysql_init(NULL);
	if (mysql==NULL)
	{
		std::cout<<"init fail!\n";
		return 0;
	}
	mysql=mysql_real_connect(mysql, "127.0.0.1", "root", "160210", "scott", 0, NULL, 0);
	if (mysql==NULL)
	{
		std::cout<<"connect fail!\n";
		return 0;
	}
	char query[]="select * from emp";
	if (mysql_query(mysql, query)!=0)
	{
		std::cout<<"query fail!\n";
		return 0;
	}//在这之前都一样
	MYSQL_RES * result=mysql_store_result(mysql);//取出结果集
	if (result != NULL)
	{
		show_result(result);//封装成一个函数,这样逻辑更清楚
		mysql_free_result(result);//释放结果集
	}
	mysql_close(mysql);
	return 0;
}

注意:一定要记住cout不能输出NULL

结果图:

数据库学习1 MySQL API使用

 

注意这个编译语句,要把MySQL的头文件路径和库文件路径给显示出来。

 

四、数据库客户端建立

#include <iostream>
#include "mysql.h"
#include <unistd.h>
 #include <string.h>

void show_result(MYSQL_RES * result, MYSQL * mysql)
{
	unsigned int result_col=mysql_num_fields(result);
	MYSQL_FIELD * fields=mysql_fetch_fields(result);
	for (int i=0; i<result_col; i++)
	{
		std::cout<<fields[i].name<<"\t";
	}
	std::cout<<"\n---------------------------------------\n";
	std::cout<<std::endl;
	MYSQL_ROW row;
	while ((row=mysql_fetch_row(result)))
		{
			for (int i=0; i<result_col; i++)
			{
				if (row[i]==NULL)
					std::cout<<"NULL"<<"\t";
				else std::cout<<row[i]<<"\t";
			}
			std::cout<<std::endl;
		}
	std::cout<<"\n---------------------------------------\n";
	std::cout<<mysql_affected_rows(mysql)<<" row in set\n";
}

int main()
{
	MYSQL * mysql=mysql_init(NULL);
	if (mysql==NULL)
	{
		std::cout<<"init fail!\n";
		return 0;
	}
	mysql=mysql_real_connect(mysql, "127.0.0.1", "root", "160210", "scott", 0, NULL, 0);
	if (mysql==NULL)
	{
		std::cout<<"connect fail!\n";
		return 0;
	}
	char buf[1024];
	while (1)
	{	
		write(STDOUT_FILENO, "yoursql>", 8);//主要就是加入从屏幕读指令,再对数据库操作
		read(STDIN_FILENO, buf, sizeof(buf));
		if (strncmp(buf, "quit", 4)==0)
		{
			std::cout<<"bye bye~\n";
			break;	
		}
		if (mysql_query(mysql, buf)!=0)
		{
			std::cout<<"query fail!\n";
			break;
		}
		int i=0;
		MYSQL_RES * result=mysql_store_result(mysql);
		if (result != NULL)
		{
			show_result(result, mysql);
			mysql_free_result(result);
		}
		else std::cout<<mysql_affected_rows(mysql)<<" row affected\n";
//mysql_affected_rows函数就是返回数据库中的数据改变了多少行,或者选择了多少行的功能。
	
	}
	mysql_close(mysql);
	return 0;
}

效果就和通过终端进入Mysql一样,如下:

数据库学习1 MySQL API使用