一、数据库连接登录及基础API

参考连接MYSQL 常用API

一、初始化

MYSQL * mysql_init(MYSQL *mysql);    // 初始化一个MYSQL 连接的实例对象
void mysql_close(MYSQL *sock);    // 释放一个MYSQL 连接实例

二、连接

mysql_real_connect()函数:
#include<mysql.h>

函数原型描述:
MYSQL *mysql_real_connect (
MYSQL *mysql,              //MYSQL *为mysql_init函数返回的指针
const char *host,          //host为null或 localhost时链接的是本地的计算机
const char *user,        //当mysql默认安装在unix(或类unix)系统中,root账户是没有密码的,因此用户名使用root,密码为null,
const char *passwd,      //密码
const char *db,          //当db为空的时候,函数链接到默认数据库,在进行 mysql安装时会存在默认的test数据库,因此此处可以使用test数据库名称,
unsigned int port,       //port端口为0, 
const char *unix_socket,   // unix连接方式,unix_socket为null时,表明不使用socket或管道机制,最后一个参数经常设置为0
unsigned long client_flag) 

mysql_real_connect()尝试与运行在主机上的MySQL数据库引擎建立连接。在你能够执行需要有效MySQL连接句柄结构的任何其他API函数之前,mysql_real_connect()必须成功完成。
返回值
如果连接成功,返回MYSQL*连接句柄。如果连接失败,返回NULL。对于成功的连接,返回值与第1个参数的值相同。

三、测试代码

#include <iostream>
#include<mysql.h>
using namespace std;
int main()
{
	//初始化mysql上下文
	MYSQL mysql;
	//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
	mysql_init(&mysql);
	const char* host = "127.0.0.1";
	const char* user = "root";
	const char* pass = "122324";     //密码
	const char* db = "mysql";		//数据库名称
	if (!mysql_real_connect(&mysql, host, user, pass, db, 3306, 0, 0))
	{
		cout << "mysql connect failed!" << mysql_error(&mysql) << endl;
	}
	else
	{
		cout << "mysql connect success!" << endl;
	}
	mysql_close(&mysql);
	mysql_library_end();
	std::cout << "Hello World!\n";
	getchar();
}

四、超时设定和自动重连

int mysql_options(MYSQL *mysql, enum mysql_option option, const char *arg)

用于设置额外的连接选项,并影响连接的行为。可多次调用该函数来设置数个选项。
可预设的选项

三、mysql数据查询接口

1.执行sql语句

int mysql_real_query(MYSQL *mysql, const char *query, unsigned long length)
//执行由“query”指向的SQL查询,它应是字符串长度字节“long”。
//正常情况下,字符串必须包含1条SQL语句,而且不应为语句添加
//终结分号(‘;’)或“\g”。如果允许多语句执行,字符串可包含
//由分号隔开的多条语句。

//如果查询成功,返回0。如果出现错误,返回非0值。
int mysql_query(MYSQL *mysql, const char *query)
//执行由“Null终结的字符串”查询指向的SQL查询

//如果查询成功,返回0。如果出现错误,返回非0值。

mysql_query()不能用于包含二进制数据的查询,应使用mysql_real_query()取而代之(二进制数据可能包含字符‘\0’,mysql_query()会将该字符解释为查询字符串结束)。

二、获取结果集
对于成功检索数据的每个查询(SELECT、SHOW、DESCRIBE、EXPLAIN),必须调用mysql_store_result()或mysql_use_result()。

MYSQL_RES *mysql_use_result(MYSQL *mysql)
MYSQL_RES *mysql_store_result(MYSQL *mysql)

//返回:MYSQL_RES结果结构。如果出现错误,返回NULL。
//区别:
/*第一种,调用mysql_store_result函数将从Mysql服务器查询的所有数据都存储到客户端,然后读取;他需要考虑缓存的大小,由max_allowed_packet限定。
第二种,调用mysql_use_result初始化检索,以便于后面一行一行的读取结果集,而它本身并没有从服务器读取任何数据,
这种方式较之第一种速度更快且所需内存更少,但它会绑定服务器,阻止其他线程更新任何表,而且必须重复执行
mysql_fetch_row读取数据,直至返回NULL,否则未读取的行会在下一次查询时作为结果的一部分返回,
故经常我们使用mysql_store_result。*/

三、遍历和清理结果集

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)
/*检索结果集的下一行。在mysql_store_result()之后使用时,如果没有要检索的行,mysql_fetch_row()返回NULL。
在mysql_use_result()之后使用时,如果没有要检索的行或出现了错误,mysql_fetch_row()返回NULL。
返回值:
下一行的MYSQL_ROW结构。如果没有更多要检索的行或出现了错误,返回NULL。*/

void mysql_free_result(MYSQL_RES *result)
/*释放由mysql_store_result()、mysql_use_result()、mysql_list_dbs()等为结果集分配的内存。
完成对结果集的操作后,必须调用mysql_free_result()释放结果集使用的内存。*/

unsigned long *mysql_fetch_lengths(MYSQL_RES *result)
//返回结果集内当前行的列的长度。
//返回:无符号长整数的数组表示各列的大小(不包括任何终结NULL字符)。如果出现错误,返回NULL。

四、代码示例

#include <iostream>
#include <mysql.h>
#include <thread>
using namespace std;
int main()
{
	//初始化mysql上下文
	MYSQL mysql;
	//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
	mysql_init(&mysql);
	const char *host = "127.0.0.1";
	//const char *host = "192.168.0.203";
	const char *user = "root";
	const char *pass = "123456";
	const char *db = "mysql";		//数据库名称
	if (!mysql_real_connect(&mysql,host, user, pass, db, 3306, 0, 0))
	{
		cout << "mysql connect failed!" << mysql_error(&mysql) << endl;
	}
	else
	{
		cout << "mysql connect success!" << endl;
	}

	//user select * from user
	// 1 执行SQL语句
	const char *sql = "select * from user";
	// mysql_real_query  sql语句中可以包含二进制数据
	// mysql_query sql语句中只能是字符串
	// 0返回表示成功 
	int re = mysql_real_query(&mysql, sql, strlen(sql));

	// Commands out of sync; you can't run this command now 
	// 执行sql语句后,必须获取结果集并且清理
	// re = mysql_query(&mysql, sql);
	if (re != 0)
	{
		cout << "mysql_real_query faied! "<< sql<<" " << mysql_error(&mysql) << endl;
	}
	else
	{
		cout << "mysql_real_query success! " << sql << endl;
	}


	//2 获取结果集

	// mysql_use_result 不实际读取数据
	//MYSQL_RES* result = mysql_use_result(&mysql);
	//mysql_store_result 读取所有数据,注意缓存大小 MYSQL_OPT_MAX_ALLOWED_PACKET 默认 64M
	MYSQL_RES* result = mysql_store_result(&mysql);
	if (!result)
	{
		cout << "mysql_use_result faied! "  << mysql_error(&mysql) << endl;
	}

	//3 遍历结果集
	MYSQL_ROW row;
	while (row = mysql_fetch_row(result))
	{
		unsigned long * lens = mysql_fetch_lengths(result);

		cout<< lens[0] << "[" << row[0] << "," << row[1] << "]" << endl;
	}

	//清理结果集
	mysql_free_result(result);
	mysql_close(&mysql);
	mysql_library_end();
	std::cout << "Hello World!\n";
	getchar();
}

四、表结构获取

在这里插入图片描述
代码,插入前面清理结果集

	//获取表字段
	MYSQL_FIELD *field = 0;
	while (field = mysql_fetch_field(result))
	{
		cout << "key:" << field->name << endl;
	}
	
	//获取表字段数量
	int fnum = mysql_num_fields(result);
	
	//3 遍历结果集
	MYSQL_ROW row;
	while (row = mysql_fetch_row(result))
	{
		unsigned long * lens = mysql_fetch_lengths(result);
		//cout<< lens[0] << "[" << row[0] << "," << row[1] << "]" << endl;
		for (int i = 0; i < fnum; i++)
		{
			cout << mysql_fetch_field_direct(result, i)->name << ":";
			if (row[i])
				cout << row[i];
			else
				cout << "NULL";
			cout<< ",";
		}
		cout <<"\n=========================================="<< endl;

	}

五、表的创建、数据插入和修改

在这里插入图片描述
创建表的sql语句:

//1 创建表
	sql = "CREATE TABLE IF NOT EXISTS `t_image`  ( \
		`id` int AUTO_INCREMENT,\
		`name` varchar(1024),\
		`path` varchar(2046),\
		`size` int,\
		PRIMARY KEY(`id`)\
		) ";
	int re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed!" << mysql_error(&mysql) << endl;
	}

添加数据:
数据添加的方式有两种:

//语法一:
insert into table_name [(column_name1,column_name2,...,column_namen)] values (value1,value2,...valuen)

//注意:
//1、字段列表的顺序可以不按照表中字段的顺序列出来,但对应值列表必须和字段名列表对应;
//2、对应值列表中的值如果是字符类型或日期类型,则需使用单引号引起来;
//3、如果没有字段列表,则值列表中值的顺序必须按照实际表中字段的默认顺序进行排列;

//语法二:
insert into to_table_name [(column_name1,column_name2,...,column_namen)]
//注意:
//insert子句中字段名列表的数目和数据类型必须和select子句中选择的字段列表的数目和数据类型相匹配。

修改数据:

update table_name set column1=value1, column2=value2……[where ……]

删除数据:

delete [from] table_name [where……]

在这里插入图片描述
完整代码

#include <iostream>
#include <mysql.h>
#include <thread>
#include <string>
#include <sstream>
#include <map>
using namespace std;
int main()
{
	//初始化mysql上下文
	MYSQL mysql;
	//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
	mysql_init(&mysql);
	const char *host = "127.0.0.1";
	//const char *host = "192.168.0.203";
	const char *user = "root";
	const char *pass = "123456";
	const char *db = "laoxiaketang";		//数据库名称

	
	if (!mysql_real_connect(&mysql,host, user, pass, db, 3306, 0, 0))
	{
		cout << "mysql connect failed!" << mysql_error(&mysql) << endl;
	}
	else
	{
		cout << "mysql connect success!" << endl;
	}
	string sql = "";

	//1 创建表
	sql = "CREATE TABLE IF NOT EXISTS `t_image`  ( \
		`id` int AUTO_INCREMENT,\
		`name` varchar(1024),\
		`path` varchar(2046),\
		`size` int,\
		PRIMARY KEY(`id`)\
		) ";
	int re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed!" << mysql_error(&mysql) << endl;
	}

	//清空数据,并恢复自增id从1开始
	sql = "truncate t_image";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed!" << mysql_error(&mysql) << endl;
	}

	//2 插入数据 CLIENT_MULTI_STATEMENTS
	for (int i = 0; i < 10; i++)
	{

		//sql = "insert `t_image` (`name`,`path`,`size`) values('test.jpg','d:/img/test.jpg',10240)";
		stringstream ss;
		ss << "insert `t_image` (`name`,`path`,`size`)values('image";
		ss << i << ".jpg','d:/img/', 10240)";
		sql = ss.str();

		re = mysql_query(&mysql, sql.c_str());
		if (re == 0)
		{
			int count = mysql_affected_rows(&mysql);
			cout << "insert mysql_affected_rows " << count << endl;
		}
		else
		{
			cout << "insert failed!" << mysql_error(&mysql) << endl;
		}
	}

	//3 修改数据
	//update t_image set `name`="test2.png",size=2000 where id=1
	sql = "update t_image set `name`='test3.png',size=2000 where id=1";
	re = mysql_query(&mysql, sql.c_str());
	if (re == 0)
	{
		int count = mysql_affected_rows(&mysql);
		cout << "update mysql_affected_rows " << count << endl;
	}
	else
	{
		cout << "update failed!" << mysql_error(&mysql) << endl;
	}

	//根据map自动生成 update sql语句
	map<string, string> kv;
	kv.insert(make_pair("name", "image_update001.png"));
	kv.insert(make_pair("size", "5000"));
	string where = " where id=2 ";
	string tmp = "";
	for (auto ptr = kv.begin(); ptr != kv.end(); ptr++)
	{
		tmp += "`";
		tmp += ptr->first;
		tmp += "`='";
		tmp += ptr->second;
		tmp += "',";
	}
	tmp += " id=id ";
	sql = "update t_image set ";
	sql += tmp;
	sql += where;

	re = mysql_query(&mysql, sql.c_str());
	if (re == 0)
	{
		int count = mysql_affected_rows(&mysql);
		cout << "update mysql_affected_rows " << count << endl;
	}
	else
	{
		cout << "update failed!" << mysql_error(&mysql) << endl;
	}

	//4 删除数据
	sql = "delete from t_image where id=1";
	re = mysql_query(&mysql, sql.c_str());
	if (re == 0)
	{
		int count = mysql_affected_rows(&mysql);
		cout << "delete mysql_affected_rows " << count << endl;
	}
	else
	{
		cout << "delete failed!" << mysql_error(&mysql) << endl;
	}
	
	//delete 不会实际删除空间,只做了标识
	sql = "delete from t_image";
	re = mysql_query(&mysql, sql.c_str());
	if (re == 0)
	{
		int count = mysql_affected_rows(&mysql);
		cout << "delete mysql_affected_rows " << count << endl;
	}
	else
	{
		cout << "delete failed!" << mysql_error(&mysql) << endl;
	}

	//实际清理了空间
	sql = "OPTIMIZE TABLE t_image";
	re = mysql_query(&mysql, sql.c_str());

	mysql_close(&mysql);
	mysql_library_end();
	std::cout << "Mysql 8.0 API!\n";
	getchar();
}

六、一次执行多条语句

在这里插入图片描述

mysql_real_connect(&mysql,host, user, pass, db, 3306, 0, CLIENT_MULTI_STATEMENTS)
//CLIENT_MULTI_STATEMENTS便是开启一次执行多条语句

代码实现:

#include <iostream>
#include <mysql.h>
#include <thread>
#include <string>
#include <sstream>
#include <map>
using namespace std;
int main()
{
	//初始化mysql上下文
	MYSQL mysql;
	//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
	mysql_init(&mysql);
	const char *host = "127.0.0.1";
	//const char *host = "192.168.0.203";
	const char *user = "root";
	const char *pass = "123456";
	const char *db = "laoxiaketang";		//数据库名称

	//CLIENT_MULTI_STATEMENTS 支持多条sql语句
	if (!mysql_real_connect(&mysql,host, user, pass, db, 3306, 0, CLIENT_MULTI_STATEMENTS))
	//if (!mysql_real_connect(&mysql, host, user, pass, db, 3306, 0, 0))
	{
		cout << "mysql connect failed!" << mysql_error(&mysql) << endl;
	}
	else
	{
		cout << "mysql connect success!" << endl;
	}
	string sql = "";

	//1 创建表
	sql = "CREATE TABLE IF NOT EXISTS `t_image`  ( \
		`id` int AUTO_INCREMENT,\
		`name` varchar(1024),\
		`path` varchar(2046),\
		`size` int,\
		PRIMARY KEY(`id`)\
		) ;";
	
	//清空数据,并恢复自增id从1开始
	sql += "truncate t_image;";

	//2 插入数据 CLIENT_MULTI_STATEMENTS
	for (int i = 0; i < 100; i++)
	{
		//sql = "insert `t_image` (`name`,`path`,`size`) values('test.jpg','d:/img/test.jpg',10240)";
		stringstream ss;
		ss << "insert `t_image` (`name`,`path`,`size`)values('image";
		ss << i << ".jpg','d:/img/', 10240);";
		sql += ss.str();
	}

	//3 修改数据
	//update t_image set `name`="test2.png",size=2000 where id=1
	sql += "update t_image set `name`='test3.png',size=2000 where id=1;";
	//4 删除数据
	sql += "delete from t_image where id=1;";
	//实际清理了空间
	sql += "select * from t_image;";

	//执行sql语句立刻返回,但语句并没有全部执行好,需要获取结果
	//把sql整个发送给mysql server,server一条条执行,返回结果
	int re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed!" << mysql_error(&mysql) << endl;
	}

	//有多个返回结果
	do
	{
		cout << "[result]";
		MYSQL_RES * result = mysql_store_result(&mysql);
		if (result) //SELECT
		{
			cout << "SELECT mysql_num_rows = " << mysql_num_rows(result) << endl;
			mysql_free_result(result);
		}
		else  // INSERT UPDATE DELETE CREATE DROP truncate
		{
			// SELECT 出错 有字段无结果
			if (mysql_field_count(&mysql) > 0)
			{
				cout << "Not retrieve result! " <<mysql_error(&mysql)<< endl;
			}
			else //INSERT UPDATE DELETE CREATE DROP truncate
			{
				//等待服务器的处理结果
				cout << mysql_affected_rows(&mysql) << " rows affected!" << endl;
			}
		}


	}
	//取下一条结果 0表示有结果
	while (mysql_next_result(&mysql) == 0);

	{
	sql = "select * from t_image";
	int re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed!" << mysql_error(&mysql) << endl;
	}
	}


	mysql_close(&mysql);
	mysql_library_end();
	std::cout << "Mysql 8.0 API!\n";
	getchar();
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值