MySQL Connect
🌟🌟hello,各位读者大大们你们好呀🌟🌟
🚀🚀系列专栏:【MySQL的学习】
📝📝本篇内容:连接;连接数据库;select
⬆⬆⬆⬆上一篇:MySQL之用户管理
💖💖作者简介:轩情吖,请多多指教(>> •̀֊•́ ) ̖́-
1.连接
在工作中,我们一般性都是使用程序来执行MySQL,因此我们需要将C++和MySQL链接起来,因此我们需要特定的库来建立他们的链接。
在我们进行安装的时候,我们可以从官网上下载,相应的安装包,然后放到Linux中进行解压,在编译代码的时候进行连接动态库。
但是其实还有一种情况,那就是我们在安装MySQL的时候,它就自动给我们下载了。当然不同的系统和版本会有出入,有的系统可能头文件和动态库都有,有的系统会缺少头文件,就像我的Ubuntu中就却少了头文件,因此我们需要下载一下,如下图

我们可以看一下我们的头文件和库在哪里

现在我们准备测试一下我们的MySQL Client,通过mysql_get_client_info()函数,来验证我们的引入是否成功

我们的编译器能够找到我们的头文件位置,但是mysql.h是在mysql目录下,需要写清楚

头文件路径(-I)和库路径(-L)可省略:因为 MySQL 的头文件 / 库文件安装在 gcc 的默认搜索路径(/usr/include/、/usr/lib/x86_64-linux-gnu/)里,编译器会自动查找。
库名(-l)必须指定:因为系统默认路径里有大量库,编译器无法判断你需要链接哪个库,必须明确指定 MySQL 对应的 mysqlclient 库名。
2.连接数据库
接下来就是要正式的连接我们的我们的数据库,然后使用SQL语句进行交互,可以参考MySQL的文档
首先我们需要先在MySQL中创建一个用户,并给他权限,我们可以再创建一个库,专门用来给这个用户使用

MySQL C API 核心函数
| 函数名 | 函数原型 | 核心作用 | 关键参数说明(重点) | 返回值说明 |
|---|---|---|---|---|
mysql_init |
MYSQL *mysql_init(MYSQL *mysql); |
初始化 MySQL 连接句柄,为后续连接做准备 | mysql:通常传 NULL,由函数自动分配并初始化连接对象 |
成功:返回初始化后的 MYSQL* 句柄 失败:返回 NULL |
mysql_real_connect |
MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, const char *user, const char *passwd, const char *db, unsigned int port, const char *unix_socket, unsigned long client_flag); |
与 MySQL 服务器建立实际连接(TCP/IP 或 Unix 套接字) | * mysql:mysql_init 返回的连接句柄 * host:服务器地址(localhost/IP) * user:登录用户名(如 root) * passwd:用户密码 * db:默认连接的数据库名(可传 NULL) * port:端口号(默认 3306,传 0 用默认) * unix_socket:Unix 套接字路径(本地连接用,传 NULL 用默认) * client_flag:连接选项(一般传 0) |
成功:返回与传入参数相同的 MYSQL* 句柄 失败:返回 NULL,可通过 mysql_error() 获取错误信息 |
mysql_query |
int mysql_query(MYSQL *mysql, const char *q); |
向服务器发送一条 SQL 语句(不支持含二进制数据的语句) | * mysql:已连接的句柄 * q:要执行的 SQL 字符串(如 SELECT * FROM table) |
成功:返回 0 失败:返回非 0 |
mysql_close |
void mysql_close(MYSQL *mysql); |
关闭与 MySQL 服务器的连接,并释放相关资源 | mysql:要关闭的连接句柄(需是已初始化/连接成功的句柄) |
无返回值(void),调用后句柄失效,不可再使用 |
第一个参数 MYSQL是 C api中一个非常重要的变量(mysql_init的返回值),里面内存非常丰富,有port,dbname,charset等连接基本参数。它也包含了一个叫 st_mysql_methods的结构体变量,该变量 里面保存着很多函数指针,这些函数指针将会在数据库连接成功以后的各种数据操作中被调用。
cpp
#include <iostream>
#include <mysql/mysql.h>
#include <string>
using namespace std;
int main()
{
// //用来查看MySQL版本
// std::cout<<"mysql client version:"<<mysql_get_client_info()<<std::endl;
//初始化库
MYSQL* mys=mysql_init(nullptr);
if(mys==nullptr)
{
cerr<<"init mysql failed"<<endl;
return 1;
}
//连接数据库
mys=mysql_real_connect(mys,"127.0.0.1","Jack","密码这边省略","conn",端口号这边省略,nullptr,0);
if(mys==nullptr)
{
cerr<<"connect mysql failed"<<endl;
return 2;
}
//SQL语句下发
string sql;
while(true)
{
cout<<"mysql>>";
if(!getline(cin,sql)||sql=="quit")
{
return 3;
}
//返回0成功
int ret=mysql_query(mys,sql.c_str());
if(ret==0)
{
cout<<"SQL query success:"<<ret<<endl;
}
else
{
cout<<"SQL query failed"<<ret<<endl;
return 4;
}
}
//关闭MySQL连接
mysql_close(mys);
return 0;
}




这里在有的版本中能插入成功,但是是乱码,建立好链接之后,获取英文没有问题,这是编码问题,因此设置链接的字符集是utf8,原始默认是latin1

并且我们此时也可以通过SQL语句来查看当前的连接情况

3.select
接下里要讲的查就比较特殊了,我们可以看一下我们输入这个SQL语句会怎样?

可以看到我们的SQL语句执行成功了,但是我们看不到内容啊,这该怎么办?
MySQL C API 结果集操作函数速查表
| 函数名 | 函数原型 | 核心作用 | 关键参数说明 | 返回值说明 | 注意事项 |
|---|---|---|---|---|---|
| mysql_store_result | MYSQL_RES *mysql_store_result(MYSQL *mysql); | 从服务器获取查询结果集 将全部结果加载到客户端内存 | mysql:已执行查询的连接句柄 | 成功:返回 MYSQL_RES* 结果集指针 失败/无结果:返回 NULL | 需调用 mysql_free_result 释放结果集 |
| mysql_num_rows | my_ulonglong mysql_num_rows(MYSQL_RES *res); | 获取结果集中的总行数 | res:结果集指针 | 返回无符号长整型的总行数 | 仅在 mysql_store_result 后有效 |
| mysql_num_fields | unsigned int mysql_num_fields(MYSQL_RES *res); | 获取结果集中的总列数 | res:结果集指针 | 返回无符号整型的总列数 | 列数与查询字段数量一致 |
| mysql_fetch_fields | MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res); | 获取所有列的元信息 (字段名/类型/长度等) | res:结果集指针 | 返回 MYSQL_FIELD* 数组指针 长度=总列数 | 可通过下标访问列信息,如 field[i].name |
| mysql_fetch_row | MYSQL_ROW mysql_fetch_row(MYSQL_RES *result); | 从结果集中逐行读取数据 每次获取下一行 | result:结果集指针 | 成功:返回 MYSQL_ROW 行数据指针 读取完毕/失败:返回 NULL | 循环读取至 NULL 结束,每行按列存储数据 |
cpp
#include <iostream>
#include <mysql/mysql.h>
#include <string>
using namespace std;
int main()
{
//初始化库
MYSQL* mys=mysql_init(nullptr);
if(mys==nullptr)
{
cerr<<"init mysql failed"<<endl;
return 1;
}
//连接数据库
mys=mysql_real_connect(mys,"localhost","Jack","密码这边省略","conn",端口号省略,nullptr,0);//127.0.0.1或者localhost都可以
if(mys==nullptr)
{
cerr<<"connect mysql failed"<<endl;
return 2;
}
//设置编码
mysql_set_character_set(mys, "utf8");
//SQL语句下发
// string sql="insert into t1 values(4,\"Jon\",\"7777777\")";
string sql="select* from t1";
mysql_query(mys,sql.c_str());
//获取查询结果
MYSQL_RES* mrs=mysql_store_result(mys);
if(mrs==nullptr)
{
cerr<<"mysql store result failed"<<endl;
return 3;
}
//获取行列
int row=mysql_num_rows(mrs);
cout<<"row:"<<row<<endl;
int fields=mysql_num_fields(mrs);
cout<<"fields:"<<fields<<endl;
//获取数据的信息
MYSQL_FIELD* myfields=mysql_fetch_fields(mrs);
for(int i=0;i<fields;i++)
{
cout<<myfields[i].name<<" ";
}
cout<<endl;
//获取数据的内容
for(int i=0;i<row;i++)
{
MYSQL_ROW myrow=mysql_fetch_row(mrs);
for(int j=0;j<fields;j++)
{
cout<<myrow[j]<<" ";
}
cout<<endl;
}
//释放结果集
mysql_free_result(mrs);
//关闭MySQL连接
mysql_close(mys);
return 0;
}

接下来就要详细说说这些函数的一些情况,包括他们的返回的类型,都是比较重要的。
sql执行完以后,如果是查询语句,我们当然还要读取数据,如果update,insert等语句,那么就看下操作成功与否即可。获取查询结果: 如果mysql_query返回成功,那么我们就通过mysql_store_result这个函数来读取结果。该函数会调用MYSQL变量中的st_mysql_methods中的 read_rows 函数指针来获取查询的结果。同时该函数会返回MYSQL_RES 这样一个变量,该变量主要用于保存查询的结果。同时该函数malloc了一片内存空间来存储查询过来的数据,所以我们一定要记的 free(result)(释放要用),不然是肯定会造成内存泄漏的。 执行完mysql_store_result以后,其实数据都已经在MYSQL_RES 变量中了。因此上面的API除了mysql_store_result基本就是读取MYSQL_RES 中的数据。


mysql会将所有的数据,读取出来的时候全部都当成字符串,因此可以理解为MYSQL_RES中有上述的结构,其实也可以看成二维数组,可以理解就行,其实数据都变成了一个个字符串,用指针被指向。
🌸🌸MySQLConnect大概就讲到这里啦,博主后续会继续更新更多Qt的相关知识,干货满满,如果觉得博主写的还不错的话,希望各位小伙伴不要吝啬手中的三连哦!如有小伙伴需要Qt的安装包可以私信我,你们的支持是博主坚持创作的动力!💪💪
