数据库—mysql、数据库编程(API)

1. Linux平台准备

        (1)安装SDK开发包的命令

sudo apt-get install libmysqlclient-dev

        (2)编译时需要链接的库:-lmysqlclient

2. mysql 的初始化和清理

#include <mysql/mysql.h>
MYSQL mysql1;  //创建句柄
mysql_init(&mysql1);  //初始化句柄
mysql_close(&mysql);  //关闭句柄

3. mysql 的连接登录

        (1)连接登录 mysql_real_connect

const char *p = "192.168.126.215";  //配置ip
const char *user = "root";  //配置用户名
const char *password" = "123456";  //配置密码
const char *db = "test";  //配置要打开的数据库

if ( mysql_real_connect(&mysql1, ip, user, password, db, 13306, nullptr, 0) == 0)  //等于0则打开失败
{
    cout<<"connect error"<<endl;
}
else
{
    cout<<"connect ok"<<endl;
}

        (2)设置断开自动重连 

//设置断开重连的功能
int ret = 1;
mysql_options(&mysql1, MYSQL_OPT_RECONNECT, &ret);
//中间的宏表示如果发现连接丢失,则启动与服务器的自动再连接;


//设置自动检测的超时时间
int timeout = 3;
mysql_options(&mysql1, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);
//中间的宏表示以秒为单位的连接超时,即超过3秒就启动重新连接

//设置是否连接的检测
if( mysql_ping(&mysql1) != 0 )
{
    cout<<"connect failed"<<endl;
}
else
{
    cout<<"connect success"<<endl;
}

4. mysql 的数据查询

        (1)执行sql语句,注意:执行sql语句后,必须获取结果集并且清理;

//创建表
string sql = "create table person(id int, name varchar(20), age int";
mysql_real_query(&mysql, sql.c_str(), sql.size());
//mysql_query(&mysql, sql.c_str());  和上面不同的是,这里并没有指定长度,执行效率没有上面的快
//对于包含二进制数据的查询,必须使用mysql_real_query(),因为二进制代码数据可能包含‘\0’字符;

//插入数据
string sql2 = "insert into person(id, name, age)values(1, 'zhangsan', 14);
mysql_real_query(&mysql, sql2.c_str(), sql2.size());

//查询数据
string sql3 = "select * from person";
mysql_real_query(&mysql, sql3.c_str(), sql3.size());

        (2)获取结果集

//获取结果集
MYSQL_RES *result;  //定义一个MYSQL_RES结构;
result = mysql_use_result(&mysql1);  //将查询结构保存在result中;
if(result == nullptr)
{
    cout<<"select error"<<endl;
}

//获取字段个数,即查询获得的结果里有几列数据
int nums = 0;  
nums = mysql_num_fields(result);  //属于表结构的获取

//获取字段名,即列的名称
MYSQL_FIELD * fields;  //字段名的数据类型的变量
fields = mysql_fetch_fields(result);  //属于表结构的获取
for(int i = 0; i < num; i++)
{
    cout<<fields[i].name<<"|";
}
cout<<endl;

//遍历显示结果
MYSQL_ROW row;  //存储每一行数据的数据类型的变量
while( (row = mysql_fetch_row(result)) != nullptr)  //mysql_fetch_row()函数从指定的结果集中获取一行数据返回给row,是数组的形式,即row内部是字符串数组指针(二级指针)
{
    for(i = 0; i < nums; i++)
    {
        cout<<row[i]<<"|";
    }
    cout<<endl;
}

        (3)清理结果集

//释放结果集的指针空间
mysql_free_result(result);

整体示例如下:

#include <iostream>
#include <mysql/mysql.h>
#include <unistd.h>

using namespace std;

int main(int argc, char **argv)
{
    MYSQL mysql1;
    mysql_init(&mysql1);

    const char *ip = "192.168.226.128";
    const char *user = "root";
    const char *password = "123456";
    const char *db = "test";

    if(mysql_real_connect(&mysql1, ip, user, password, db, 13306, nullptr,0) == 0)
    {
        cout<<"connect error"<<endl;
    }
    else
    {
        cout<<"connect ok"<<endl;
    }
    
    string sql = "create table person(id int, name varchar(20), age int)";
    mysql_real_query(&mysql1, sql.c_str(), sql.size());

    // string sql1 = "select"

    int ret = 1;
    mysql_options(&mysql1, MYSQL_OPT_RECONNECT, &ret);

    int timeout = 3;
    mysql_options(&mysql1, MYSQL_OPT_CONNECT_TIMEOUT, &timeout);

    // while(1)  //测试断开重连功能
    // {
    //     if(mysql_ping(&mysql1) != 0)
    //     {
    //         cout<<"connect failed"<<endl;
    //     }
    //     else
    //     {
    //         // cout<<"connnect ok"<<endl;
    //     }
    //     sleep(1);
    // }

    string sql2 = "insert into person(id, name, age)values(1,'zhangsan',12)";
    mysql_real_query(&mysql1, sql2.c_str(), sql2.size());

    string sql22 = "insert into person(id, name, age)values(2,'lisi',16)";
    mysql_real_query(&mysql1, sql22.c_str(), sql22.size());

    string sql3 = "select * from person";
    mysql_real_query(&mysql1, sql3.c_str(), sql3.size());

    MYSQL_RES * result = mysql_use_result(&mysql1);
    if(result == nullptr)
    {
        cout<<"select error"<<endl;
    }

    int nums = 0;
    nums = mysql_num_fields(result);
    cout<<"nums = "<<nums<<endl;

    MYSQL_FIELD * fields = mysql_fetch_fields(result);
    for(int i = 0; i < nums; i++)
    {
        cout<<fields[i].name<<"|";
    }
    cout<<endl;

    MYSQL_ROW row;
    while((row = mysql_fetch_row(result)) != nullptr)
    {
        for(int i =0; i < nums; i++)
        {
            cout<<row[i]<<"|";
        }
        cout<<endl;
    }

    mysql_free_result(result);
    mysql_close(&mysql1);
    return 0;
}

运行结果如下:

5. mysql 显示中文

//设置中文的思路是统一设置字符集为utf8;
const char * csname = "utf8";
mysql_set_character_set(&mysql, csname);

6. 图片存储与读取保存的例子

#include <iostream>
#include <mysql/mysql.h>
#include <thread>
#include <string>
#include <sstream>
#include <map>
#include <chrono>
#include <fstream>
using namespace std;
using namespace chrono;

int main()
{
	//初始化mysql上下文
	MYSQL mysql;
	//单线程模式 mysql_init自动调用 mysql_library_init 线程不安全
	mysql_init(&mysql);
	const char* host = "192.168.226.128";
	//const char *host = "192.168.0.203";
	const char* user = "root";
	const char* pass = "123456";
	const char* db = "test";		//数据库名称

	//CLIENT_MULTI_STATEMENTS 支持多条sql语句
	if (!mysql_real_connect(&mysql, host, user, pass, db, 13306, 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 创建好存放二进制数据的表 t_data
	sql = "CREATE TABLE IF NOT EXISTS `t_data` (\
		`id` int AUTO_INCREMENT,\
		`name` varchar(1024),\
		`data` blob,\
		`size` int,\
		PRIMARY KEY(`id`))";

	int re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << mysql_error(&mysql) << endl;
	}

	//2 清空表 truncate t_data
	sql = "truncate t_data";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cerr << mysql_error(&mysql) << endl;
	}

	//3 初始化stmt mysql_stmt_init
	MYSQL_STMT* stmt = mysql_stmt_init(&mysql);
	if (!stmt)
	{
		cerr << "mysql_stmt_init failed!" << mysql_error(&mysql) << endl;
	}

	//4 预处理sql语句
	sql = "INSERT INTO `t_data` (name,data,size) VALUES(?,?,?)";
	if (mysql_stmt_prepare(stmt, sql.c_str(), sql.size()))
	{
		cerr << "mysql_stmt_prepare failed!" << mysql_stmt_error(stmt) << endl;
	}

	//5 打开并读取文件
	string path = ".//";
	string filename = "mysql.jpg";

	cout << path + filename << endl;

	//读取二进制
	fstream in(path + filename, ios::in | ios::binary);
	if (!in.is_open())
	{
		cerr << "file " << filename << " open failed!" << endl;
	}
	//文件指针移动到结尾处
	in.seekg(0, ios::end);
	//文件大小和文件二进制地址
	int filesize = in.tellg();
	//回到开头
	in.seekg(0, ios::beg);

	char* data = new char[filesize];
	int readed = 0; //已经读了多少
	while (!in.eof())
	{
		in.read(data + readed, filesize - readed);
		//读取了多少字节
		if (in.gcount() <= 0)
			break;
		readed += in.gcount();
	}

	in.close();

	//6 绑定字段
	MYSQL_BIND bind[3] = { 0 };
	bind[0].buffer_type = MYSQL_TYPE_STRING;  //name 文件名
	bind[0].buffer = (char*)filename.c_str();
	bind[0].buffer_length = filename.size();

	bind[1].buffer_type = MYSQL_TYPE_BLOB;   //data 文件二进制内容
	bind[1].buffer = data; //二进制文件
	bind[1].buffer_length = filesize;

	//文件大小
	bind[2].buffer_type = MYSQL_TYPE_LONG;
	bind[2].buffer = &filesize;

	if (mysql_stmt_bind_param(stmt, bind) != 0)
	{
		cerr << "mysql_stmt_bind_param failed! " << mysql_stmt_error(stmt) << endl;
	}

	//7 执行stmt sql
	if (mysql_stmt_execute(stmt) != 0)
	{
		cerr << "mysql_stmt_execute failed! " << mysql_stmt_error(stmt) << endl;
	}
	delete data;
	mysql_stmt_close(stmt);


	sql = "select * from t_data";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cerr << "mysql query failed!" << mysql_error(&mysql) << endl;
	}
	//获取结果集
	MYSQL_RES* res = mysql_store_result(&mysql);
	if (!res)
	{
		cerr << "mysql_store_result failed!" << mysql_error(&mysql) << endl;
	}
	//取一行数据
	MYSQL_ROW row = mysql_fetch_row(res);
	if (!row)
	{
		cerr << "mysql_fetch_row failed!" << mysql_error(&mysql) << endl;
	}
	cout << row[0] << " " << row[1] << " " << row[3] << endl;

	//获取每列数据的大小
	unsigned long* lens = mysql_fetch_lengths(res);
	int fnum = mysql_num_fields(res);
	for (int i = 0; i < fnum; i++)
	{
		cout << "[" << lens[i] << "]";
	}
	filename = "out_";
	filename += row[1];
	fstream out(filename, ios::out | ios::binary);
	if (!out.is_open())
	{
		cerr << "open file  " << filename << " failed!" << endl;
	}
	out.write(row[2], lens[2]);
	out.close();


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


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

猜你喜欢

转载自blog.csdn.net/m0_72814368/article/details/131144203
今日推荐