MySQL Connect

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 套接字) * mysqlmysql_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的安装包可以私信我,你们的支持是博主坚持创作的动力!💪💪

相关推荐
m0_518019481 小时前
使用Python操作文件和目录(os, pathlib, shutil)
jvm·数据库·python
lifewange1 小时前
SQL中的聚合函数有哪些
android·数据库·sql
阿贵---2 小时前
使用Python进行PDF文件的处理与操作
jvm·数据库·python
稻草猫.2 小时前
MyBatis-Plus高效开发全攻略
java·数据库·后端·spring·java-ee·mybatis·mybatis-plus
Seven972 小时前
InnoDB存储结构全解析:行页区段与单表2000W行的关系
mysql
人道领域2 小时前
Day | 09 【苍穹外卖:订单售后业务】
java·数据库·后端
minji...2 小时前
Linux 进程间通信(一)进程间通信与匿名管道
linux·运维·服务器·数据结构·数据库·c++
XDHCOM2 小时前
ORA-12532: TNS:invalid argument 故障解析,Oracle报错远程处理技巧与修复方法分享
数据库·oracle
IMPYLH2 小时前
Linux 的 csplit 命令
linux·运维·服务器·数据库