目录
准备工作
测试是否安装成功
C/C++语言访问
官方文档
接口介绍使用
mysql_init()
mysql_close()
补充1:makefile编写
mysql_real_connect()
测试1:编译链接
mysql_query()
测试2:SQL语句测试
改
增
删
查
错误1:SQL语句错误
错误2:编码错误
mysql_set_character_set()
测试3:编码错误测试
查询的后序处理
mysql_store_result()
mysql_num_rows()
mysql_num_fields()
测试4:行列获取测试
mysql_fetch_row()
测试5:读取数据测试
mysql_fetch_fields()
测试6:读取数据测试
mysql_free_result()
补充2:事务
全部的测试代码
准备工作
首先我们创建一个用户 参考上文MySQL·用户管理-CSDN博客
赋予权限
登入与权限测试
方法一:动静态链接
C库下载
链接:MySQL :: MySQL Community Downloads
找到C版本支持的第三方库下载对应版本即可
方法二:yum源直接安装
参考下文:
MySQL卸载、安装、登入与配置_yum 卸载mysql-CSDN博客
曾经安装过了,就不再演示了
假如还是没有可以尝试直接安装
yum install mysql-devel
如果是一路看过来的话,可能你们的yum源需要更新了,我使用的源目前是有一些是无法访问的,但是到现在还没有什么影响,所以为了防止出现意外,就继续使用了。具体错误如下
测试是否安装成功
这是一个返回MySQL版本的一个函数,我们可以用它来做测试
#include <iostream>
#include <mysql/mysql.h>
int main()
{
std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
return 0;
}
直接编译是无法成功的,我们需要指定动态库
只指明库名也是无法成功的,我们还需要添加路径
g++ -o mytest test.cc -L/lib64/mysql/ -lmysqlclient
这样我们发现编译成功了,并且成功返回了MySQL的版本号
没有找到可以是因为这个的指明是无法找到,需要重新配置环境
你可能需要把环境添加到这里面来
通常情况下,MySQL的安装程序会自动配置好所需的环境变量和库路径,你可能不需要手动进行这些操作。
解决方法可以参考下面这里的回答
如果在头文件中不指明文件夹的话,则需要在编译指令中添加文件夹
#include <iostream>
#include <mysql.h>
int main()
{
std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
return 0;
}
直接编译会报错
添加大 -I 选项
C/C++语言访问
官方文档
MySQL :: MySQL Documentation
找到C的,对应版本
官方接口 :MySQL :: MySQL 5.7 C API Developer Guide :: 4 C API Function Reference
接口介绍使用
mysql_init()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.37 mysql_init()
创建一个mysql类的结构体
MySQL类里面就是一些信息
mysql_close()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.5 mysql_close()
关闭释放这个句柄
创建并且关闭
#include <iostream>
#include <mysql/mysql.h>
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
// 关闭释放该句柄
mysql_close(my);
return 0;
}
编译测试
补充1:makefile编写
mytest:test.cc
g++ -o $@ $^ -std=c++11 -L/lib64/mysql -lmysqlclient
.PHONY:clean
clean:
rm -f mytest
#上面的原式 g++ -o mytest test.cc -std=c++11 -L/lib64/mysql -lmysqlclient
#其中$@ $^表示自动变量,前者表示目标项,后者表示全部依赖项,$<表示第一个依赖项
mysql_real_connect()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.54 mysql_real_connect()
链接数据库
#include <iostream>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_close(my);
return 0;
}
测试1:编译链接
为了方便演示,我们先创建一张表
create table user(
id bigint primary key auto_increment,
name varchar(32) not null,
age int not null,
telphone varchar(32) unique
);
显然这里是没有什么问题的
我们可以通过下面这条SQL语句查看当前链接的用户信息
show processlist;
我们对代码进行修改,让它不要这么快退出,让我们看到链接的信息
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
sleep(10);
std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_close(my);
return 0;
}
这一次我们看到了
显然目前没有出现什么错误
mysql_query()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.53 mysql_query()
下达指令
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
std::string sql;
while(true)
{
std::cout << "MySQL>>> ";
if(!std::getline(std::cin, sql) || sql == "quit")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(my, sql.c_str());
if(n == 0)
{
std::cout << sql << " success: " << n << std::endl;
}
else
{
std::cerr << sql << " failed: " << n << std::endl;
}
}
// sleep(10);
// std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_close(my);
return 0;
}
测试2:SQL语句测试
改
不过其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
std::string sql = "update user set name='Jimmy' where id=2";
int n = mysql_query(my, sql.c_str());
if(n == 0) std::cout << sql << " success: " << n << std::endl;
else std::cerr << sql << " failed: " << n << std::endl;
/*
// 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
std::string sql;
while(true)
{
std::cout << "MySQL>>> ";
if(!std::getline(std::cin, sql) || sql == "quit")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(my, sql.c_str());
if(n == 0)
{
std::cout << sql << " success: " << n << std::endl;
}
else
{
std::cerr << sql << " failed: " << n << std::endl;
}
}
*/
// sleep(10);
// std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_close(my);
return 0;
}
显然这里是没有出现什么错误的,我们能够使用语言来实现对数据的控制
下面进行增删改查测试
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
// std::string sql = "update user set name='Jimmy' where id=2"; // 改
// std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
// std::string sql = "delete from user where id=1";
std::string sql = "select * from user";
int n = mysql_query(my, sql.c_str());
if(n == 0) std::cout << sql << " success: " << n << std::endl;
else std::cerr << sql << " failed: " << n << std::endl;
/*
// 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
std::string sql;
while(true)
{
std::cout << "MySQL>>> ";
if(!std::getline(std::cin, sql) || sql == "quit")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(my, sql.c_str());
if(n == 0)
{
std::cout << sql << " success: " << n << std::endl;
}
else
{
std::cerr << sql << " failed: " << n << std::endl;
}
}
*/
// sleep(10);
// std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_close(my);
return 0;
}
增
删
查
我们会发现查这个操作是无法进行的,因为查是这四种操作最不好处理的,因为这个消息并不是让服务端去显示,在使用的时候,我们肯定是要让用户去看到这个查的消息,这个我们在后面进行详细介绍
错误1:SQL语句错误
从这里看到,当用户传递的SQL语句不正确的时候,MySQL的服务端是不会进行处理的,当然这也是我们可以预料到的,因为MySQL保证对数据的操作,只要是成功的,就一定是正确的SQL语句,反之如果失败的,就一定是错误的语句
错误2:编码错误
我们可以看到,这里插入中文的话,是会出现乱码的,但是我们知道的,在一开始我们就已经配置好了MySQL的编码格式,那么为什么这里还是会出现呢?
如下我们配置里面是使用的utf8的
这其实是因为编码的不一致导致的,建立好链接之后,获取英文没有问题,如果获取中文是乱码:设置链接的默认字符集是utf8,原始默认是latin1
mysql_set_character_set()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.69 mysql_set_character_set()
设置编码格式
测试3:编码错误测试
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
mysql_set_character_set(my, "utf8");
// std::string sql = "update user set name='Jimmy' where id=2"; // 改
// std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
// std::string sql = "delete from user where id=1";
// std::string sql = "select * from user";
std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";
int n = mysql_query(my, sql.c_str());
if(n == 0) std::cout << sql << " success: " << n << std::endl;
else std::cerr << sql << " failed: " << n << std::endl;
/*
// 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
std::string sql;
while(true)
{
std::cout << "MySQL>>> ";
if(!std::getline(std::cin, sql) || sql == "quit")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(my, sql.c_str());
if(n == 0)
{
std::cout << sql << " success: " << n << std::endl;
}
else
{
std::cerr << sql << " failed: " << n << std::endl;
}
}
*/
// sleep(10);
// std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_close(my);
return 0;
}
这下插入就没有编码不一致带来的乱码了
查询的后序处理
mysql_store_result()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.77 mysql_store_result()
把查询到的结果转存到某个地方,MYSQL_RES
MYSQL_RES的内容其实就是一个结构体
mysql_num_rows()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.49 mysql_num_rows()
拿取行
mysql_num_fields()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.48 mysql_num_fields()
拿取列
其中 my_ulonglong 其实就是 unsigned long long 类型的数据
测试4:行列获取测试
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
mysql_set_character_set(my, "utf8");
// std::string sql = "update user set name='Jimmy' where id=2"; // 改
// std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
// std::string sql = "delete from user where id=4";
// std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";
std::string sql = "select * from user";
int n = mysql_query(my, sql.c_str());
if(n == 0) std::cout << sql << " success: " << n << std::endl;
else
{
std::cerr << sql << " failed: " << n << std::endl;
return 3;
}
MYSQL_RES *res = mysql_store_result(my);
if(nullptr == res)
{
std::cerr << "mysql_store_result error" << std::endl;
return 4;
}
my_ulonglong rows = mysql_num_rows(res); // 拿取行
my_ulonglong fields = mysql_num_fields(res); // 拿取列
std::cout << "行: " << rows << std::endl;
std::cout << "列: " << fields << std::endl;
/*
// 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
std::string sql;
while(true)
{
std::cout << "MySQL>>> ";
if(!std::getline(std::cin, sql) || sql == "quit")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(my, sql.c_str());
if(n == 0)
{
std::cout << sql << " success: " << n << std::endl;
}
else
{
std::cerr << sql << " failed: " << n << std::endl;
}
}
*/
// sleep(10);
// std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_close(my);
return 0;
}
看到结果,我们确实拿到了具体的行和列
当我们测试拿取一条数据的时候,也是正确的,用where进行筛选
mysql_fetch_row()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.21 mysql_fetch_row()
自动迭代遍历,获取数据
一个新的宏,MYSQL_ROW ,其实就是一个指针,我们将其看做一个指向一个二维数组的指针就行了
测试5:读取数据测试
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
mysql_set_character_set(my, "utf8");
// std::string sql = "update user set name='Jimmy' where id=2"; // 改
// std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
// std::string sql = "delete from user where id=4";
// std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";
// std::string sql = "select * from user where id=3";
std::string sql = "select * from user";
int n = mysql_query(my, sql.c_str());
if(n == 0) std::cout << sql << " success: " << n << std::endl;
else
{
std::cerr << sql << " failed: " << n << std::endl;
return 3;
}
MYSQL_RES *res = mysql_store_result(my);
if(nullptr == res)
{
std::cerr << "mysql_store_result error" << std::endl;
return 4;
}
// 到这里都是和结果集有关的,MYSQL_RES
my_ulonglong rows = mysql_num_rows(res); // 拿取行
my_ulonglong fields = mysql_num_fields(res); // 拿取列
std::cout << "行: " << rows << std::endl;
std::cout << "列: " << fields << std::endl;
// 将其当作一个二维数组去遍历即可
for(my_ulonglong i = 0; i < rows; ++i)
{
MYSQL_ROW row = mysql_fetch_row(res); // 和迭代器很像,会自己维护一个指针,自动遍历
for(my_ulonglong j = 0; j < fields; ++j)
{
std::cout << row[j] << "\t"; // *(row+j) 其实就是解引用
}
std::cout << std::endl;
}
/*
// 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
std::string sql;
while(true)
{
std::cout << "MySQL>>> ";
if(!std::getline(std::cin, sql) || sql == "quit")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(my, sql.c_str());
if(n == 0)
{
std::cout << sql << " success: " << n << std::endl;
}
else
{
std::cerr << sql << " failed: " << n << std::endl;
}
}
*/
// sleep(10);
// std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_close(my);
return 0;
}
可以看到我们拿取到了结果,并且没有错误
mysql_fetch_fields()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.19 mysql_fetch_fields()
获取列名信息
MYSQL_FIELD
这里是不是很熟悉,这里就是MySQL里面的那一套
测试6:读取数据测试
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
mysql_set_character_set(my, "utf8");
// std::string sql = "update user set name='Jimmy' where id=2"; // 改
// std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
// std::string sql = "delete from user where id=4";
// std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";
// std::string sql = "select * from user where id=3";
std::string sql = "select * from user";
int n = mysql_query(my, sql.c_str());
if(n == 0) std::cout << sql << " success: " << n << std::endl;
else
{
std::cerr << sql << " failed: " << n << std::endl;
return 3;
}
MYSQL_RES *res = mysql_store_result(my);
if(nullptr == res)
{
std::cerr << "mysql_store_result error" << std::endl;
return 4;
}
// 到这里都是和结果集有关的,MYSQL_RES
my_ulonglong rows = mysql_num_rows(res); // 拿取行
my_ulonglong fields = mysql_num_fields(res); // 拿取列
std::cout << "行: " << rows << std::endl;
std::cout << "列: " << fields << std::endl;
// 将其当作一个二维数组去遍历即可
// 读取属性
MYSQL_FIELD *fields_arry = mysql_fetch_fields(res);
for(my_ulonglong i = 0; i < fields; i++)
{
std::cout << fields_arry[i].name << "\t";
}
std::cout << "\n";
// 读取内容
for(my_ulonglong i = 0; i < rows; ++i)
{
MYSQL_ROW row = mysql_fetch_row(res); // 和迭代器很像,会自己维护一个指针,自动遍历
for(my_ulonglong j = 0; j < fields; ++j)
{
std::cout << row[j] << "\t"; // *(row+j) 其实就是解引用
}
std::cout << std::endl;
}
// 读取数据库名,表名
std::cout << fields_arry[0].db << " " << fields_arry[0].table << std::endl;
/*
// 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
std::string sql;
while(true)
{
std::cout << "MySQL>>> ";
if(!std::getline(std::cin, sql) || sql == "quit")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(my, sql.c_str());
if(n == 0)
{
std::cout << sql << " success: " << n << std::endl;
}
else
{
std::cerr << sql << " failed: " << n << std::endl;
}
}
*/
// sleep(10);
// std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_close(my);
return 0;
}
我们可以看到,其实MySQL的客户端本质上就是对这些数据进行处理,本身就是看做对字符串的处理,原理很简单
mysql_free_result()
MySQL :: MySQL 5.7 C API Developer Guide :: 5.4.25 mysql_free_result()
释放结果集
官方提供了专门用来释放结果集的函数
使用起来也很简单,就像C++里面的free函数一样就行
mysql_free_result(res);
补充2:事务
我们都知道每一次的单SQL语句在MySQL看来都是一个事务,所以我们这里并没有测试事务的启动和提交,我们知道这一点就行了,通常我们会把一堆SQL语句放一起提交,那么MySQL就会把它当成一个事务,所以我们在代码上一般也不怎么讨论事务的启动和提交,当然了我们也可以开启事务,MySQL也提供了相应的函数比如下面这几个
my_bool STDCALL mysql_autocommit(MYSQL * mysql, my_bool auto_mode);
my_bool STDCALL mysql_commit(MYSQL * mysql);
my_bool STDCALL mysql_rollback(MYSQL * mysql);
其实我们也可以用mysql_query()这个提交来开启事务,比如提交begin,commit,rollback都能够实现,看自己需求
全部的测试代码
#include <iostream>
#include <unistd.h>
#include <string>
#include <mysql/mysql.h>
// const std::string host = "127.0.0.1";
const std::string host = "localhost"; // 使用本地回环也可以
const std::string user = "connector";
const std::string passwd = "123456";
const std::string db = "conn";
const unsigned int port = 8080;
int main()
{
// std::cout << "mysql client version: " << mysql_get_client_info() << std::endl;
// 创建一个mysql句柄
MYSQL *my = mysql_init(nullptr);
if(nullptr == my)
{
std::cerr << "init MySQL error" << std::endl;
return 1;
}
if(mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)
{
std::cerr << "connect MySQL error" << std::endl;
return 2;
}
mysql_set_character_set(my, "utf8");
// std::string sql = "update user set name='Jimmy' where id=2"; // 改
// std::string sql = "insert into user (name, age, telphone) values ('peter', 19, '987654321')";
// std::string sql = "delete from user where id=4";
// std::string sql = "insert into user (name, age, telphone) values ('张三', 19, '666666666')";
// std::string sql = "select * from user where id=3";
std::string sql = "select * from user";
int n = mysql_query(my, sql.c_str());
if(n == 0) std::cout << sql << " success: " << n << std::endl;
else
{
std::cerr << sql << " failed: " << n << std::endl;
return 3;
}
MYSQL_RES *res = mysql_store_result(my);
if(nullptr == res)
{
std::cerr << "mysql_store_result error" << std::endl;
return 4;
}
// 到这里都是和结果集有关的,MYSQL_RES
my_ulonglong rows = mysql_num_rows(res); // 拿取行
my_ulonglong fields = mysql_num_fields(res); // 拿取列
std::cout << "行: " << rows << std::endl;
std::cout << "列: " << fields << std::endl;
// 将其当作一个二维数组去遍历即可
// 读取属性
MYSQL_FIELD *fields_arry = mysql_fetch_fields(res);
for(my_ulonglong i = 0; i < fields; i++)
{
std::cout << fields_arry[i].name << "\t";
}
std::cout << "\n";
// 读取内容
for(my_ulonglong i = 0; i < rows; ++i)
{
MYSQL_ROW row = mysql_fetch_row(res); // 和迭代器很像,会自己维护一个指针,自动遍历
for(my_ulonglong j = 0; j < fields; ++j)
{
std::cout << row[j] << "\t"; // *(row+j) 其实就是解引用
}
std::cout << std::endl;
}
// 读取数据库名,表名
std::cout << fields_arry[0].db << " " << fields_arry[0].table << std::endl;
/*
// 其实我们并不需要这么麻烦去写一个MySQL的客户端,我们只需要使用即可
std::string sql;
while(true)
{
std::cout << "MySQL>>> ";
if(!std::getline(std::cin, sql) || sql == "quit")
{
std::cout << "bye bye" << std::endl;
break;
}
int n = mysql_query(my, sql.c_str());
if(n == 0)
{
std::cout << sql << " success: " << n << std::endl;
}
else
{
std::cerr << sql << " failed: " << n << std::endl;
}
}
*/
// sleep(10);
// std::cout << "connnect success" << std::endl;
// 关闭释放该句柄
mysql_free_result(res);
mysql_close(my);
return 0;
}