当前位置: 首页 > news >正文

MySQL·C/C++访问数据库

目录

准备工作

测试是否安装成功

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.ccg++ -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_RESmy_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_RESmy_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_RESmy_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;
}

相关文章:

MySQL·C/C++访问数据库

目录 准备工作 测试是否安装成功 C/C语言访问 官方文档 接口介绍使用 mysql_init() mysql_close() 补充1&#xff1a;makefile编写 mysql_real_connect() 测试1&#xff1a;编译链接 mysql_query() 测试2&#xff1a;SQL语句测试 改 增 删 查 错误1&#x…...

python.tkinter设计标记语言(渲染2-渲染器)

TOC 前言 本文仅作为笔记记录。 在前文中&#xff0c;我们通过标记意义解释生成了带有明确渲染要求的参数组&#xff0c;以<title>为例&#xff0c;我们获取了title, level两个明确的渲染标记&#xff0c;这一部分由Tin标记解释器完成&#xff0c;不需要编写者花费过多…...

Cadence学习笔记 Day0 Cadence17.4环境安装

当然是选择“吴法安装” 直接跟着吴川斌博客的方法来就可以了&#xff0c;这里大致记录一下我的安装步骤&#xff1a; 安装许可证管理器破解许可证管理器安装软件以及补丁破解软件 获取 直接放出链接&#xff1a;吴川斌的博客 下载得到&#xff1a; 一、安装许可证管理器&am…...

k8s创建secret并在container中获取secret

k8s创建secret并在container中获取secret 本文使用的deployment和service与我的上一篇文章一样。link也放在下面了&#xff0c;如果不懂什么事deployment和service&#xff0c;可以先看我的上一篇文章。 k8s使用kustomize来部署应用 下面我们将通过创建secret开始。secret是我…...

Leetcode每日一题之仅仅反转字母(C++)

在学习之余对于知识的巩固也尤为重要&#xff0c;不论难度高低&#xff0c;都会对代码的理解有所加深&#xff0c;下面我们开始练习 思路解析 关于本题的核心思路就是如何判断字符串中元素是否为字母以及如何遍历字符串以达到仅反转的目的&#xff0c;这里用到的知识就是关于 s…...

PDF预览:利用vue3-pdf-app实现前端PDF在线展示

目录 PDF预览&#xff1a;利用vue3-pdf-app实现前端PDF在线展示 一、vue3-pdf-app组件介绍及其优点 1、vue3-pdf-app是什么 2、作用与场景 3、类似的插件 二、项目初始化与依赖安装 1、初始化Vue3项目 2、安装依赖 三、集成vue3-pdf-app插件 1、引入插件 2、配置组件…...

【OpenCV C++20 学习笔记】拉普拉斯(Laplace)二阶求导-边缘检测

拉普拉斯二阶求导 原理拉普拉斯算子(Laplacian Operator) API实例 原理 在OpenCV中&#xff0c;Sobel算法可以对图片中的值求一阶导数&#xff0c;从而计算出图片中的边缘线。其原理如下面的示意图&#xff1a; 那么&#xff0c;如果再求一次导数的&#xff0c;即求二阶导数&…...

MySQL的下载和安装步骤

一、数据库概述 我们先来了解三个概念&#xff1a;数据库、数据库管理系统、SQL。 名称全称简称数据库存储数据的仓库&#xff0c;数据是有组织的进行存储DataBase&#xff08;DB&#xff09;数据库管理系统操纵和管理数据库的大型软件DataBase Management System (DBMS)SQL操…...

Java国际版同城服务美容美发到店服务上门服务系统

&#x1f30d;全球美妆新风尚&#xff01;国际版同城服务&#xff0c;美容美发一键享 &#x1f3d9;️【国际视野&#xff0c;同城便捷】&#x1f3d9;️ 在这个全球化的时代&#xff0c;美丽不再受地域限制&#xff01;国际版同城服务系统&#xff0c;将全球顶尖的美容美发资…...

硬件模拟的基本原理

具体来说&#xff0c;这种设计方法减少了集成电路 (IC) 设计和开发的设计迭代次数&#xff0c;并且广泛适用于所有电力电子设计。我详细介绍了我在快速上市 IC 开发方面的经验&#xff0c;并将该方法与其他旨在缩短产品开发时间的技术进行了对比。 产品开发流程 图 1&#xff…...

WPF学习(8)- Button按钮

1. 用法解析 Button因为继承了ButtonBase&#xff0c;而ButtonBase又继承了ContentControl&#xff0c;所以&#xff0c;Button可以通过设置Content属性来设置要显示的内容。例如 <Button Content"确定"/>我们使用Button的时机&#xff0c;通常是鼠标点击事件…...

Flutter GPU 是什么?为什么它对 Flutter 有跨时代的意义?

Flutter 3.24 版本引入了 Flutter GPU 概念的新底层图形 API flutter_gpu &#xff0c;还有 flutter_scene 的 3D 渲染支持库&#xff0c;它们目前都是预览阶段&#xff0c;只能在 main channel 上体验&#xff0c;并且依赖 Impeller 的实现。 Flutter GPU 是 Flutter 内置的底…...

第6章>>实验7:PS(ARM)端Linux RT与PL端FPGA之间(通过Memory存储器进行通信和交互)《LabVIEW ZYNQ FPGA宝典》

1、实验内容 上一节实验里面介绍的Reg寄存器通道比较适合在PS端和PL端之间传递标量数据&#xff0c;也就是单个元素&#xff0c;如果要传递多个元素的数组或者连续数据流的话&#xff0c;Reg寄存器通道就不是很合适了。 本节实验我们向大家讲解如何借助Memory存储器通道在PS&am…...

通用前端的学习

通用前端的概念 通用前端的概念是我自创的&#xff0c;也是我多年开发全栈时的个人理解&#xff0c;结合自己对各种语言的比较&#xff0c;发现前端都具有几个特征&#xff0c;而这几个特征&#xff0c;很多人只能用具体的表象来描述&#xff0c;比如用安卓方式来说明&#xf…...

git本地仓库关联多个远程仓库时git pull失败问题

目录 问题描述 原因 解决办法 1.多个远程仓库需有继承关系 2.一句命令实现创建本地分支且与远程分支关联 问题描述 今天操作本地仓库时&#xff0c;关联了两个远程仓库&#xff0c;欲在本地仓库创建一个分支&#xff0c;与第二个远程仓库的某个分支关联&#xff0c;然后将…...

人工智能(AI)、Web 3.0和元宇宙三者联系、应用及未来发展趋势的详细分析

人工智能&#xff08;AI&#xff09;、Web 3.0和元宇宙作为当前科技领域的热门话题&#xff0c;它们之间存在着紧密的联系&#xff0c;并在各自领域内展现出广泛的应用和未来的发展趋势。以下是对这三者联系、应用及未来发展趋势的详细分析&#xff1a; 一、人工智能&#xff…...

【IEEE出版 | 高校主办】第三届人工智能、物联网和云计算技术国际会议(AIoTC 2024)

第三届人工智能、物联网和云计算技术国际会议&#xff08;AIoTC 2024&#xff09; 2024 3rd International Conference on Artificial Intelligence, Internet of Things and Cloud Computing Technology 2024年9月13-15日 | 中国武汉 重要信息 大会官网&#xff1a;www.ic…...

PTA 7-4 BCD解密

7-4 BCD解密&#xff08;10分&#xff09; BCD数是用一个字节来表达两位十进制的数&#xff0c;每四个比特表示一位。所以如果一个BCD数的十六进制是0x12&#xff0c;它表达的就是十进制的12。但是小明没学过BCD&#xff0c;把所有的BCD数都当作二进制数转换成十进制输出了。于…...

计算机网络中拥塞控制的门限值怎么设置

拥塞避免的门限值设置主要涉及到加权随机早期检测&#xff08;‌WRED&#xff09;‌技术&#xff0c;‌这是一种拥塞避免机制&#xff0c;‌通过为每个队列设定一对低门限和高门限值来实现。‌具体来说&#xff0c;‌当队列长度小于低门限时&#xff0c;‌不丢弃报文&#xff0…...

解锁肥胖焦虑的枷锁:拥抱自我,健康前行

在这个颜值经济盛行、信息爆炸的时代&#xff0c;肥胖似乎成了许多人心中难以言说的痛。社交媒体上满屏的“A4腰”、“锁骨养鱼”&#xff0c;无形中给大众套上了一层名为“肥胖焦虑”的沉重枷锁。但请相信&#xff0c;真正的美丽与幸福&#xff0c;从不以体重秤上的数字为衡量…...

利用ngx_stream_return_module构建简易 TCP/UDP 响应网关

一、模块概述 ngx_stream_return_module 提供了一个极简的指令&#xff1a; return <value>;在收到客户端连接后&#xff0c;立即将 <value> 写回并关闭连接。<value> 支持内嵌文本和内置变量&#xff08;如 $time_iso8601、$remote_addr 等&#xff09;&a…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

DAY 47

三、通道注意力 3.1 通道注意力的定义 # 新增&#xff1a;通道注意力模块&#xff08;SE模块&#xff09; class ChannelAttention(nn.Module):"""通道注意力模块(Squeeze-and-Excitation)"""def __init__(self, in_channels, reduction_rat…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)

笔记整理&#xff1a;刘治强&#xff0c;浙江大学硕士生&#xff0c;研究方向为知识图谱表示学习&#xff0c;大语言模型 论文链接&#xff1a;http://arxiv.org/abs/2407.16127 发表会议&#xff1a;ISWC 2024 1. 动机 传统的知识图谱补全&#xff08;KGC&#xff09;模型通过…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍

文章目录 前言限流限制并发的实际理解限流令牌桶代码实现结果分析令牌桶lua的模拟实现原理总结&#xff1a; 滑动窗口代码实现结果分析lua脚本原理解析 限并发分布式信号量代码实现结果分析lua脚本实现原理 双注解去实现限流 并发结果分析&#xff1a; 实际业务去理解体会统一注…...

涂鸦T5AI手搓语音、emoji、otto机器人从入门到实战

“&#x1f916;手搓TuyaAI语音指令 &#x1f60d;秒变表情包大师&#xff0c;让萌系Otto机器人&#x1f525;玩出智能新花样&#xff01;开整&#xff01;” &#x1f916; Otto机器人 → 直接点明主体 手搓TuyaAI语音 → 强调 自主编程/自定义 语音控制&#xff08;TuyaAI…...

NLP学习路线图(二十三):长短期记忆网络(LSTM)

在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...