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

**前言:**本节内容介绍使用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指令, 在官方文档中给出的函数如下:

int
mysql_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_t
mysql_num_rows(MYSQL_RES *result); //获取行
unsigned int
mysql_num_fields(MYSQL_RES *result); //获取列

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

MYSQL_ROW
mysql_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 << "	";}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] << "	";}cout << endl;}mysql_close(my);return 0;
}

然后打印就打印出来了:

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

void
mysql_free_result(MYSQL_RES *result)

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15347.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

postgreSQL16.6源码安装

1.获取源码 从PostgreSQL: File Browser获取tar.bz2或者tar.gz源码 2.解压 tar xf postgresql-version.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# tar xf postgresql-16.6.tar.bz2 roothwz-VMware-Virtual-Platform:/usr/local# ll 总计 24324 drwxr-xr-x 12 ro…

音频进阶学习十一——离散傅里叶级数DFS

文章目录 前言一、傅里叶级数1.定义2.周期信号序列3.表达式DFSIDFS参数含义 4.DFS公式解析1&#xff09;右边解析 T T T、 f f f、 ω \omega ω的关系求和公式N的释义求和公式K的释义 e j ( − 2 π k n N ) e^{j(\frac{-2\pi kn}{N})} ej(N−2πkn​)的释义 ∑ n 0 N − 1 e…

【kafka系列】Topic 与 Partition

Kafka 的 Topic&#xff08;主题&#xff09; 和 Partition&#xff08;分区&#xff09; 是数据组织的核心概念&#xff0c;它们的映射关系及在 Broker 上的分布直接影响 Kafka 的性能、扩展性和容错能力。以下是详细解析&#xff1a; 一、Topic 与 Partition 的映射关系 Top…

卷积神经网络CNN如何处理语音信号

卷积神经网络&#xff08;CNN&#xff09;在处理语音数据时通常不直接处理原始的一维波形信号&#xff0c;而是处理经过预处理的二维语音特征图。以下是CNN处理语音数据时的常见数据类型和步骤&#xff1a; 1. 语音信号预处理 语音信号通常是一维的时间序列&#xff08;波形信…

【MQ】Spring3 中 RabbitMQ 的使用与常见场景

一、初识 MQ 传统的单体架构&#xff0c;分布式架构的同步调用里&#xff0c;无论是方法调用&#xff0c;还是 OpenFeign 难免会有以下问题&#xff1a; 扩展性差&#xff08;高耦合&#xff0c;需要依赖对应的服务&#xff0c;同样的事件&#xff0c;不断有新需求&#xff0…

GB/T 43698-2024 《网络安全技术 软件供应链安全要求》标准解读

一、43698-2024标准图解 https://mmbiz.qpic.cn/sz_mmbiz_png/rwcfRwCticvgeBPR8TWIPywUP8nGp4IMFwwrxAHMZ9Enfp3wibNxnfichT5zs7rh2FxTZWMxz0je9TZSqQ0lNZ7lQ/640?wx_fmtpng&fromappmsg 标准在线预览&#xff1a; 国家标准|GB/T 43698-2024 相关标准&#xff1a; &a…

Linux系统-centos防火墙firewalld详解

Linux系统-centos7.6 防火墙firewalld详解 1 firewalld了解 CentOS 7.6默认的防火墙管理工具是firewalld&#xff0c;它取代了之前的iptables防火墙。firewalld属于典型的包过滤防火墙或称之为网络层防火墙&#xff0c;与iptables一样&#xff0c;都是用来管理防火墙的工具&a…

Gitlab中如何进行仓库迁移

需求&#xff1a;之前有一个自己维护的新仓库A&#xff0c;现在需要将这个仓库提交并覆盖另一个旧的仓库B&#xff0c;需要保留A中所有的commit信息。 1.方法一&#xff1a;将原有仓库A导出后再导入到新的仓库B中 适用场景&#xff1a;新的仓库B是一个待建仓库&#xff0c;相当…

微信点餐系统小程序ssm+论文源码调试讲解

第4章 系统设计 一个成功设计的系统在内容上必定是丰富的&#xff0c;在系统外观或系统功能上必定是对用户友好的。所以为了提升系统的价值&#xff0c;吸引更多的访问者访问系统&#xff0c;以及让来访用户可以花费更多时间停留在系统上&#xff0c;则表明该系统设计得比较专…

01单片机上电后没有正常运行怎么办

单片机上电后没有运转, 首先要检查什么? 1、单片机供电是否正常? &电路焊接检查 如果连最基本的供电都没有,其它都是空谈啊!检查电路断路了没有?短路了没有?电源合适吗?有没有虚焊? 拿起万用表之前,预想一下测量哪里?供电电压应该是多少?对PCB上电压测量点要…

【Java基础】为什么不支持多重继承?方法重载和方法重写之间区别、Exception 和 Error 区别?

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;Java基础面经 &#x1f4da;本系列文章为个…

c++ haru生成pdf输出饼图

#define PI 3.14159265358979323846 // 绘制饼图的函数 void draw_pie_chart(HPDF_Doc pdf, HPDF_Page page, float *data, int data_count, float x, float y, float radius) { float total 0; int i; // 计算数据总和 for (i 0; i < data_count; i) { tot…

Linux 创建进程 fork()、vfork() 与进程管理

Linux 创建进程 fork、vfork、进程管理 一、Linux的0号、1号、2号进程二、Linux的进程标识三、fork() 函数1、基本概念2、函数特点3、用法以及应用场景&#xff08;1&#xff09;父子进程执行不同的代码&#xff08;2&#xff09;进程执行另一个程序 4、工作原理 四、vfork() 函…

【漫话机器学习系列】082.岭回归(或脊回归)中的α值(alpha in ridge regression)

岭回归&#xff08;Ridge Regression&#xff09;中的 α 值 岭回归&#xff08;Ridge Regression&#xff09;是一种 带有 L2​ 正则化 的线性回归方法&#xff0c;用于处理多重共线性&#xff08;Multicollinearity&#xff09;问题&#xff0c;提高模型的泛化能力。其中&am…

电脑重启后vscode快捷方式失效,找不到code.exe

今天打开电脑发现vscode的快捷方式失效了&#xff0c;提示code.exe被删除或移动。 解决方法 查看vscode安装目录&#xff0c;发现多了一个_文件夹&#xff0c;包括code.exe在内的其他文件都被移动到了这个文件夹下。 将里面内容都移动到microsoft vs code文件夹下&#xff0c…

[权限提升] Linux 提权 维持 — 系统错误配置提权 - Sudo 滥用提权

关注这个专栏的其他相关笔记&#xff1a;[内网安全] 内网渗透 - 学习手册-CSDN博客 0x01&#xff1a;Sudo 滥用提权原理 Sudo 是一个 Linux 系统管理命令&#xff0c;它允许系统管理员授予普通用户以指定身份执行指定命令的权限。该命令不仅减少了 Root 用户的登录时间和管理时…

激活函数篇 04 —— softmax函数

将模型的输出转换为概率分布&#xff0c;使得模型能够输出每个类别的概率值。 Softmax ( a i ) e a i ∑ j 1 n e a j \text{Softmax}(a_i)\frac{e^{a_i}}{\sum_{j1}^n e^{a_j}} Softmax(ai​)∑j1n​eaj​eai​​ 其中&#xff0c; a i a_i ai​ 是输入向量中的第 i i i 个…

【韩顺平linux】部分上课笔记整理

整理一下一些韩顺平老师上课时候的笔记 课程&#xff1a;【小白入门 通俗易懂】韩顺平 一周学会Linux linux环境&#xff1a;使用阿里云服务器 笔记参考 &#xff1a; [学习笔记]2021韩顺平一周学会Linux 一、自定义函数 基本语法 应用实例&#xff1a; 计算两个参数的和…

redis底层数据结构——简单动态字符串

文章目录 概述什么时候用C里面的字符串什么时候使用SDS使用场景 SDS定义SDS与C语言的字符串差异常数时间复杂度获取字符串长度杜绝缓冲区溢出减少修改字符串时带来的内存重分配次数1.空间预分配2.情性空间释放 二进制安全兼容部分C字符串函数总结 开始讲述动态字符串前我们先问…

使用 POI-TL 和 JFreeChart 动态生成 Word 报告

文章目录 前言一、需求背景二、方案分析三、 POI-TL JFreeChart 实现3.1 Maven 依赖3.3 word模板设置3.2 实现代码 踩坑 前言 在开发过程中&#xff0c;我们经常需要生成包含动态数据和图表的 Word 报告。本文将介绍如何结合 POI-TL 和 JFreeChart&#xff0c;实现动态生成 W…