当前位置:首页 » 《关于电脑》 » 正文

【MySQL】深度学习数据库开发技术:使用C/C++语言访问数据库

27 人参与  2024年12月30日 14:01  分类 : 《关于电脑》  评论

点击全文阅读


        前言:本节内容介绍使用C/C++访问数据库, 包括对数据库的增删查改操作。 主要是学习一些接口的调用, 废话不多说, 开始我们的学习吧!

        ps:本节内容比较容易, 友友们放心观看哦!

目录

准备mysql库

使用mysql库 

编译文件

官方API文档

对象的创建和关闭

链接数据库

下达sql指令

select语句


准备mysql库

        其实我们访问mysql不只是使用命令行进行访问, 我们未来访问数据库一定是一个程序对数据库进行访问, 而程序其实就是代码。所以未来我们可以使用代码来访问数据库, 这里我们使用C/C++代码对数据库进行访问。

        首先我们创建一个非root级别用户和一个数据库:

        然后我们要知道, 我们访问数据要有对应的开发包, 这些开发包我们可以直接在apt里面找到下载安装。

sudo apt install -y libmysqlclient-dev

        安装好了之后我们就能在/usr/include/路径下面看到mysql目录

        这个 里面包含着我们需要的文件, 像什么mysql.h就是我们所需要的。

        然后在/usr/lib/x86_64-linux-gnu里面也有我们的mysql的连接库:

使用mysql库 

编译文件

        然后使用库,系统会默认搜索的路径是/lib/include路径, 然后我们要使用的mysql.h头文件在/lib/include西面的/mysql目录下面, 所以我们包含头文件要使用mysql/mysql.h:

#include<mysql/mysql.h>  

        mysql_get_client_info函数可以打印当前mysql的版本信息。 

#include<iostream>#include<mysql/mysql.h>  using namespace std;int main(){    cout << "mysql_client version: " << mysql_get_client_info() << endl;           return 0;}

        然后编译可能会出现问题:

        这是因为因为我们编译的时候系统找不到链接的库, 所以需要我们使用-l指令指定路径:

 -lmysqlclient;

        然后就能运行成功了: 

官方API文档

        然后就是我们要对数据库进行增删查改,我们可以去mysql的官方文档进行查看对应的资料

先进入官方网站,点击文档:

然后下滑找到并点击C API:

然后点击function就能看到我们常用的一些函数了:

         知道了这些之后, 下面开始学习增删查改:

对象的创建和关闭

#include<iostream>#include<mysql/mysql.h>  using namespace std;int main(){    MYSQL* my = mysql_init(nullptr);    if (nullptr)    {        cerr << "init MySQL error" << endl;        return 1;    }        mysql_close(my);    return 0;}

        这里面的MYSQL类型就类似于我们C语言里面的FILE类型, 都是一个句柄。如果成功了就是返回一个非空的值, 就代表我们获得了拒柄。 

        既然获得句柄, 那么最后情况下还要关闭数据库, 释放一系列资源。 使用mysql_close函数, 就类似于我们关闭文件的操作。
 

链接数据库

在官方文档中给出的mysql链接函数如下。 

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所在的ip地址, 这里我们采用本地环回;  第三个参数就是就是使用的用户名; 第四个参数就是对应用户的密码; 第五个参数就是数据库的名称;第六个参数就是端口号;剩下的参数默认即可。返回值就是MYSQL*也就是句柄, 如果是nullptr就是连接失败。

#include<iostream>#include<mysql/mysql.h>  #include<string>using namespace std;const string host = "localhost";const string user = "mian_yang";const string passwd = "XXXXXXXXXXXXXXXX";const string db = "school_book_manage";const unsigned int port = 3306;int main(){    MYSQL* my = mysql_init(nullptr);    if (nullptr)    {        cerr << "init MySQL error" << endl;        return 1;    }    //    if (mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)    {        cerr << "connect error" << endl;        return 0;    }    //    cout << "connect success" << endl;    mysql_close(my);    return 0;}

然后我们编译一下运行一下: 

下达sql指令

        然后我们就可以使用函数下达sql指令, 在官方文档中给出的函数如下:        

intmysql_query(MYSQL *mysql,            const char *stmt_str)

其中第一个参数就是我们的句柄。 然后第二个参数就是我们要下达的指令。返回值如果为零就执行成功了, 如果不为零, 就执行失败了。然后下面是代码:

#include<iostream>#include<mysql/mysql.h>  #include<string>using namespace std;const string host = "localhost";const string user = "mian_yang";const string passwd = "MYhylk563_al36huz.6";const string db = "school_book_manage";const unsigned int port = 3306;int main(){    MYSQL* my = mysql_init(nullptr);    if (nullptr)    {        cerr << "init MySQL error" << endl;        return 1;    }    //    if (mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)    {        cerr << "connect error" << endl;        return 0;    }    //    cout << "connect success" << endl;    string sql;    while (true)    {        cout << ">>";        if (!getline(cin, sql) || sql == "quit") break;        int n = mysql_query(my, sql.c_str());        if (n == 0)         {            cout << sql << "  success "<<endl;        }        else cout << sql << "  error" << endl;    }    mysql_close(my);    return 0;}

        运行的时候我们就来测验一下进行插入: 

        然后也可以看到我们的sql语句执行成功了!

        现在我们插入一下李四, 插入中文, 我们查看一下结果:

        我们会看到李四被正常的插入进去了。 这里博主要说的是, 对于mysql8.0来说, 博主使用的是mysql8.0, 这里使用插入函数插入中文会正常插入。 但是如果是5.7版本的mysql, 那么这里如果插入中文插入的就是一堆乱码。所有的乱码问题都是客户端和服务器双方没有形成编码一致。比如说服务端使用utf8, 而客户端使用的是其他的编码方式。编码不一致,那么我编码使用的是utf8, 你解码使用的是其他的方式。 那么就乱码了。

        这里我们的8.0数据库, 表编码都是utf8mb4的,说明我们的客户端也是utf8mb4的。如果我们设置成其他的再插入就是一堆乱码, 这里试验一下:使用mysql_set_character_set函数设置解码方式:

    mysql_set_character_set(my, "latin1");

 

        插入成功: 

 

        可以看到, 解码出来就是一堆乱码。

         现在问题来了, 我们上面的插入试验成功了, select语句呢? 我们的select语句是查, 要打印给我们一系列信息。 这里博主可以说一下实验结果, 结果是执行成功, 但是没有打印结果。 其他的像update, delete操作都能执行成功。 只有select 虽然执行成功但是没有给我们显示信息, 这是因为其他的sql语句都只需要执行成功即可, 但是select语句还要进行后续的处理, 比如打印。 所以select语句怎么处理呢? 

select语句

        我们查出来的是一种表结构。 如果我们查出来有四条数据, 那么就有四行。 如果我们查出来的表有四列属性, 那么查出来就有四列。 我们要知道我们要查的是一些数据。 那么这些数据在mysql内部就一定要有对应的内存空间保存这个数据。 mysql将所有的数据读取出来的时候全部都当作字符串了。 然后有一个MYSQL_RES对象,MYSQL_RES对象就是将这些数据进行整合一下。 我们可以把MYSQL_RES对象看成一个数组的指针, 这个数组里面存储的数据类型是char**类型。 数组的大小表示一共有多少条记录。 

然后这些元素都指向一个char*的数组:

        这个char*元素指向的就是我们的表结构里面的属性元素。 所以未来我们就可以把MYSQL_RES堪称一个char** XXX[]数组。

        所以, 这个MYSQL_RES其实就是我们使用select语句之后返回的结果, 这个结果的集合就在MYSQL_RES对象中。 未来我们想要去除其中的对象, 我们需要先获取这个结果集里面的行, 里面的列:

MYSQL_RES *mysql_store_result(MYSQL *mysql); //获得结果集uint64_tmysql_num_rows(MYSQL_RES *result); //获取行unsigned intmysql_num_fields(MYSQL_RES *result); //获取列

        为了更好的遍历, mysql提供了一种数据结构MYSQL_ROW, 方便我们更好的遍历, 以后我们就可以直接把这个RES结果集当成一个二维数组来使用。这个MYSQL_ROW就相当于迭代器, 我们每次调用, 它都可以自动加。

MYSQL_ROWmysql_fetch_row(MYSQL_RES *result);

        然后我们不仅有数据, 还有我们的列名(列属性)所以我们就可以获取一下列名:

MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *result)

这个函数的返回值是一个结构里, 这个结构体里面有着列名称、取别名后的原生列名称、 属于哪个表、属于哪个数据库等等:

        未来我们想要的就是这个name字段。 我们然后就可以向遍历数组一样遍历这个列属性,打印出来列属性。

所以, 下面为全部的代码:

#include<iostream>#include<mysql/mysql.h>  #include<string>using namespace std;const string host = "localhost";const string user = "mian_yang";    const string passwd = "MYhylk563_al36huz.6";const string db = "school_book_manage";const unsigned int port = 3306;int main(){    MYSQL* my = mysql_init(nullptr);    if (nullptr)    {        cerr << "init MySQL error" << endl;        return 1;    }    //    if (mysql_real_connect(my, host.c_str(), user.c_str(), passwd.c_str(), db.c_str(), port, nullptr, 0) == nullptr)    {        cerr << "connect error" << endl;        return 0;    }    //    cout << "connect success" << endl;    string sql = "select * from user";    int n = mysql_query(my, sql.c_str());    if (n == 0) cout << sql << " success" << endl;    else     {        cerr << sql << " error" << endl;        return 3;    }    //    MYSQL_RES* res = mysql_store_result(my);    if (res == nullptr)     {        cerr << "res error" << endl;        return 4;    }    MYSQL_FIELD* fields = mysql_fetch_fields(res);    my_ulonglong cols = mysql_num_rows(res);    for (int i = 0; i < cols; i++)    {        cout << fields[i].name << "\t";    }    cout << endl;       my_ulonglong rows = mysql_num_rows(res);    for (int i = 0; i < rows; i++)    {        MYSQL_ROW row = mysql_fetch_row(res);        for (int j = 0; j < cols; j++)        {            cout << row[j] << "\t";        }        cout << endl;    }    mysql_close(my);    return 0;}

 然后打印就打印出来了:

 对于MYSQL_RES, 其实MYSQL_RES就是在内存中申请了一大块内存空间, 所以最后我们还要free这块空间。而上层用户如果使用free释放空间就会造成内存泄漏或者使用内部的原生指针太麻烦。 所以就提供了一个接口:

voidmysql_free_result(MYSQL_RES *result)

        这个函数就是系统提供的释放我们的结果集。 

-------------------------------------------------------------------------------------------------------------------------------- 

——————以上就是本节全部内容哦, 如果对友友们有帮助的话可以关注博主, 方便学习更多知识哦!!!  


点击全文阅读


本文链接:http://zhangshiyu.com/post/209259.html

<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

最新文章

  • 林晚夏江肆年(进错房,嫁给八零最牛特种兵在线阅读)全文免费阅读无弹窗大结局_(林晚夏江肆年)进错房,嫁给八零最牛特种兵在线阅读免费阅读全文最新章节列表_笔趣阁(林晚夏江肆年) -
  • 进错房,嫁给八零最牛特种兵完整版阅读小说(林晚夏江肆年)全文免费阅读无弹窗大结局_(进错房,嫁给八零最牛特种兵完整版阅读)林晚夏江肆年免费阅读全文最新章节列表_笔趣阁(进错房,嫁给八零最牛特种兵完整版阅读) -
  • 新雪藏旧事全文全文(商云萝周砚京)全文免费阅读无弹窗大结局_(新雪藏旧事全文小说免费阅读)最新章节列表_笔趣阁(新雪藏旧事全文) -
  • 在线免费小说重生七零替嫁:不嫁教授,嫁军官_乔珊珊乔婉月新热门小说_热门小说乔珊珊乔婉月
  • 免费小说《冯云漪厉晋泽》已完结(冯云漪厉晋泽)热门小说大结局全文阅读笔趣阁
  • 祁兰湘邵黎晖小说_祁兰湘邵黎晖完整版大结局小说免费阅读
  • 完整免费小说老公心疼青梅将她留宿新房,却将怀孕的我赶出家门(乔玥傅慎行姜禾)_老公心疼青梅将她留宿新房,却将怀孕的我赶出家门(乔玥傅慎行姜禾)完本小说免费阅读(乔玥傅慎行姜禾)
  • 新雪藏旧事:结局+番外+完结免费小说在线阅读_小说完结推荐新雪藏旧事:结局+番外+完结商云萝周砚京热门小说
  • 初逢青山梦长安(顾怀瑾沈书妤)阅读 -
  • 无删减版《绝对权力:从天崩开局走上官途巅峰》在线免费阅读
  • 《绝对权力:从天崩开局走上官途巅峰》小说在线试读,《绝对权力:从天崩开局走上官途巅峰》最新章节目录
  • 裴泽苏星辰何娇(满目星辰不及你小说)精彩章节在线阅读

    关于我们 | 我要投稿 | 免责申明

    Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1