二、mysql事务处理及读写二进制文件

在这里插入图片描述

一、事务

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

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_video`  ( \
		`id` int AUTO_INCREMENT,\
		`name` varchar(1024),\
		`path` varchar(2046),\
		`size` int,\
		PRIMARY KEY(`id`)\
		) ENGINE=InnoDB;";  //设置支持事务回滚的 InnoDB引擎
	int re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
	}
	//清理表数据
	sql = "truncate t_video";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
	}

	// 事务
	//1 开始事务
	//START TRANSACTION;
	sql = "START TRANSACTION";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
	}

	//2 设置为手动提交事务
	//set autocommit = 0
	sql = "set autocommit = 0";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
	}

	//3 sql语句

	//插入三条数据,回滚
	for (int i = 0; i < 3; i++)
	{
		sql = "insert into t_video (name) values('test three!')";
		re = mysql_query(&mysql, sql.c_str());
		if (re != 0)
		{
			cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
		}
	}

	//4 回滚ROLLBACK MYISAM 不支持
	sql = "ROLLBACK";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
	}
	for (int i = 0; i < 1000; i++)
	{
		sql = "insert into t_video (name) values('test three!')";
		re = mysql_query(&mysql, sql.c_str());
		if (re != 0)
		{
			cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
		}
	}

	//5 COMMIT  
	sql = "COMMIT";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
	}

	//6 恢复自动提交 set autocommit = 1
	sql = "set autocommit = 1";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
	}


	sql = "select count(*) from t_video";
	re = mysql_query(&mysql, sql.c_str());
	if (re != 0)
	{
		cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
	}
	MYSQL_RES * res = mysql_store_result(&mysql);
	if (res)
	{
		//取得第一行数据
		MYSQL_ROW row = mysql_fetch_row(res);
		if (row)
		{
			cout << "t_video count(*) = " << row[0] << endl;
		}
	}
	auto start = system_clock::now();
	//单条语句插入1千条数据
	for (int i = 0; i < 1000; i++)
	{
		sql = "insert into t_video (name,path) values('single','0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789')";
		re = mysql_query(&mysql, sql.c_str());
		if (re != 0)
		{
			cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
		}
	}
	auto end = system_clock::now();
	//转换为毫秒 1000
	auto dur = duration_cast<milliseconds> (end - start);
	cout << "1 单条语句插入1千条数据" << dur.count()/1000.<<"秒" << endl;

	//多条语句插入1千条数据

	{
		auto start = system_clock::now();
		sql = "";
		//单条语句插入1千条数据
		for (int i = 0; i < 1000; i++)
		{
			sql += "insert into t_video (name,path) values('single','0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789');";
		}

		re = mysql_query(&mysql, sql.c_str());
		if (re != 0)
		{
			cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
		}
		do
		{
			cout << mysql_affected_rows(&mysql) << flush;
		} while (mysql_next_result(&mysql) == 0);
		auto end = system_clock::now();
		//转换为毫秒 1000
		auto dur = duration_cast<milliseconds> (end - start);
		cout << "2 多条语句插入1千条数据" << dur.count() / 1000. << "秒" << endl;
	}


	//事务插入1千条数据
	{
		//1 开始事务
		//START TRANSACTION;
		sql = "START TRANSACTION";
		re = mysql_query(&mysql, sql.c_str());
		if (re != 0)
		{
			cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
		}
		auto start = system_clock::now();
		//单条语句插入1千条数据
		for (int i = 0; i < 1000; i++)
		{
			sql = "insert into t_video (name,path) values('single','0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789')";
			re = mysql_query(&mysql, sql.c_str());
			if (re != 0)
			{
				cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
			}
			else
				cout << mysql_affected_rows(&mysql) << flush;

		}


		//2 设置为手动提交事务
		//set autocommit = 0
		sql = "set autocommit = 0";
		re = mysql_query(&mysql, sql.c_str());
		if (re != 0)
		{
			cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
		}



		sql = "COMMIT";
		re = mysql_query(&mysql, sql.c_str());
		if (re != 0)
		{
			cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
		}
		sql = "set autocommit = 1";
		re = mysql_query(&mysql, sql.c_str());
		if (re != 0)
		{
			cout << "mysql_query failed! " << mysql_error(&mysql) << endl;
		}

		auto end = system_clock::now();
		//转换为毫秒 1000
		auto dur = duration_cast<milliseconds> (end - start);
		cout << "3 事务插入1千条数据" << dur.count() / 1000. << "秒" << endl;

	}




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

二、向数据库写入二进制文件和从数据库取出二进制文件

#include <iostream>
#include <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 = "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 创建好存放二进制数据的表 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 filename = "mysql.jpg";


	
	//读取二进制
	fstream in(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);


	//8 查询二进制数据,并保存问文件
	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";
	getchar();
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值