【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)
这个函数就是系统提供的释放我们的结果集。
--------------------------------------------------------------------------------------------------------------------------------
——————以上就是本节全部内容哦, 如果对友友们有帮助的话可以关注博主, 方便学习更多知识哦!!!
相关文章:

【MySQL】深度学习数据库开发技术:使用CC++语言访问数据库
**前言:**本节内容介绍使用C/C访问数据库, 包括对数据库的增删查改操作。 主要是学习一些接口的调用, 废话不多说, 开始我们的学习吧! ps:本节内容比较容易, 友友们放心观看哦! 目录 准备mysql…...

LabVIEW化工实验室设备故障实时监测
化工实验室中,各类设备的运行状态直接影响实验的精度与安全性。特别是重要分析仪器的突发故障,可能导致实验中断或数据失效。为了实现设备运行状态的实时监控与故障快速响应,本文提出了一套基于LabVIEW的解决方案,通过多参数采集、…...
单例模式懒汉式、饿汉式(线程安全)
饿汉式单线程安全吗 饿汉式单例(Eager Singleton)是线程安全的。这种实现方式在类加载时就创建了单例实例,因此在多线程环境中,不存在多个线程同时创建实例的问题。 饿汉式单例的实现 以下是一个饿汉式单例的示例: …...

Cursor登录按钮点击没反应
问题 系统:Windows11 Cursor:Cursor 0.44.9 当安装Cursor打开进行登录时,点击Sign in没反应 解决方案 1.打开window11的设置 2.点击应用中的默认应用 3.在设置应用程序的默认值中搜索Google(没有Google浏览器的尝试下载一个&a…...
论文实现:Reactive Nonholonomic Trajectory Generation via Parametric Optimal Control
1. 多项式螺旋 曲率: κ ( s ) a 0 a 1 s a 2 s 2 a 3 s 3 a 4 s 4 a 5 s 5 \begin{align} \kappa(s) a_0 a_1s a_2s^2 a_3s^3 a_4s^4 a_5s^5 \end{align} κ(s)a0a1sa2s2a3s3a4s4a5s5 机器人朝向: θ ( s ) a 0 s a 1 …...

基于单片机中药存放环境监测系统的实现
基于单片机中药存放环境监测系统的实现 项目开发背景 随着现代中药的广泛应用,中药材的存储环境对其质量有着至关重要的影响。温湿度、烟雾、火灾等环境因素,若不加以控制,将会导致中药材失效或变质。因此,设计一个基于单片机的…...

九垠赢+商业管理系统 Common.ashx 文件上传致RCE漏洞复现
0x01 产品简介 九垠赢+商业管理系统是基于互联网技术的进销存管理软件,适用于新零售背景下各种业态的线上线下一体化的商超经营管理。赢+ERP以商业管理系统为底座,融合了多种软、硬件解决方案,实现了从企业、供应商、三方平台到顾客等日常管理的全线数字化、智能化和移动化…...
速盾:服务器CDN加速解析的好处有哪些呢?
随着互联网应用的普及,越来越多的企业开始关注如何提升网站的访问速度和用户体验。为了实现这一目标,许多企业选择使用CDN(内容分发网络)来加速网站的内容分发。CDN通过在全球范围内分布多个节点,将内容缓存到离用户最…...
C++ 设计模式:备忘录模式(Memento Pattern)
链接:C 设计模式 链接:C 设计模式 - 状态模式 备忘录模式(Memento Pattern)是一种行为设计模式,它允许在不破坏封装性的前提下捕获和恢复对象的内部状态。这个模式在需要保存和恢复对象状态的场景中非常有用ÿ…...
Android 系统 Activity 系统层深度定制的方法、常见问题以及解决办法
Android 系统 Activity 系统层深度定制的方法、常见问题以及解决办法 目录 引言Activity 系统层概述Activity 系统架构图Activity 系统层深度定制的方法 4.1 自定义 Activity 生命周期4.2 自定义 Activity 启动流程4.3 自定义 Activity 转场动画4.4 自定义 Activity 窗口管理4…...

PDF怎么压缩得又小又清晰?5种PDF压缩方法
PDF 文件在日常办公与学习中使用极为频繁,可想要把它压缩得又小又清晰却困难重重。一方面,PDF 格式本身具有高度兼容性,集成了文字、图像、矢量图等多样元素,压缩时难以兼顾不同元素特性,稍不注意,文字就会…...

YK人工智能(三)——万字长文学会torch深度学习
2.1 张量 本节主要内容: 张量的简介PyTorch如何创建张量PyTorch中张量的操作PyTorch中张量的广播机制 2.1.1 简介 几何代数中定义的张量是基于向量和矩阵的推广,比如我们可以将标量视为零阶张量,矢量可以视为一阶张量,矩阵就是…...

关于CISP报名费用详情
CISP即“注册信息安全专业人员”,是中国信息安全测评中心实施的国家认证项目,旨在培养信息安全领域的专业人才。对于有意报考CISP的考生而言,了解报名考试费用是备考过程中不可或缺的一环。 CISP的报名考试费用主要包括培训费用、考试费用、…...
vim 按下esc后取消高亮
配置 ideavimrc文件 " 按下 Esc 键时自动取消高亮 " 在普通模式下按下 Esc 键取消高亮 nnoremap <Esc> :nohlsearch<CR> " 在插入模式下按下 Esc 键取消高亮 inoremap <Esc> <Esc>:nohlsearch<CR>" 额外:当退出…...

SwiftUI:多语言实现富文本插值
实现的UI需求: 要求: 英文显示:3068 people have joined this plan today! 中文显示:今日有 3068 人已加入此计划! 实现代码: Text(AttributedString(localized:"**\(payPeoples)** people have joi…...

操作系统基础
概念 控制和管理操作系统软件和硬件 用户观点:用户和计算机之间的接口 基本概念 特征 并发,共享,虚拟,异步 功能 处理机管理,存储器管理,文件管理,设备管理 作为用户和硬件接口 命令接口&am…...
函数调用流程可用工具
方法 1、gdb,这个网上很多找找就有 2、tcmalloc,直接在调用的地方调一个malloc就可以看到调用的流程,具体见tcmalloc 3、backtrace,个人感觉这么最方便,具体见backtrace...
UniApp 页面布局基础
一、UniApp 页面布局简介 在当今的移动应用开发领域,跨平台开发已成为一种主流趋势。UniApp作为一款极具影响力的跨平台开发框架,凭借其“一套代码,多端运行”的特性,为开发者们提供了极大的便利,显著提升了开发效率。…...

2D图像测量到3D点云之物体三维尺寸测量!!!!
0,引言 本文将从双目采集的2D图像到3D点云进行转化,并进行物体尺寸测量,旨在为读者展示2D图像如何关联3D点云,并进行相关工业应用。 将2D图像转化为3D点云,并进行物体尺寸测量的技术,在工业领域有着广泛的…...

[TOTP]android kotlin实现 totp身份验证器 类似Google身份验证器
背景:自己或者公司用一些谷歌身份验证器或者microsoft身份验证器,下载来源不明,或者有广告,使用不安全。于是自己写一个,安全放心使用。 代码已开源:shixiaotian/sxt-android-totp: android totp authenti…...
大数据学习(132)-HIve数据分析
🍋🍋大数据学习🍋🍋 🔥系列专栏: 👑哲学语录: 用力所能及,改变世界。 💖如果觉得博主的文章还不错的话,请点赞👍收藏⭐️留言Ǵ…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

使用Spring AI和MCP协议构建图片搜索服务
目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式(本地调用) SSE模式(远程调用) 4. 注册工具提…...

【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...

AI语音助手的Python实现
引言 语音助手(如小爱同学、Siri)通过语音识别、自然语言处理(NLP)和语音合成技术,为用户提供直观、高效的交互体验。随着人工智能的普及,Python开发者可以利用开源库和AI模型,快速构建自定义语音助手。本文由浅入深,详细介绍如何使用Python开发AI语音助手,涵盖基础功…...
Docker拉取MySQL后数据库连接失败的解决方案
在使用Docker部署MySQL时,拉取并启动容器后,有时可能会遇到数据库连接失败的问题。这种问题可能由多种原因导致,包括配置错误、网络设置问题、权限问题等。本文将分析可能的原因,并提供解决方案。 一、确认MySQL容器的运行状态 …...
MFE(微前端) Module Federation:Webpack.config.js文件中每个属性的含义解释
以Module Federation 插件详为例,Webpack.config.js它可能的配置和含义如下: 前言 Module Federation 的Webpack.config.js核心配置包括: name filename(定义应用标识) remotes(引用远程模块࿰…...
k8s从入门到放弃之HPA控制器
k8s从入门到放弃之HPA控制器 Kubernetes中的Horizontal Pod Autoscaler (HPA)控制器是一种用于自动扩展部署、副本集或复制控制器中Pod数量的机制。它可以根据观察到的CPU利用率(或其他自定义指标)来调整这些对象的规模,从而帮助应用程序在负…...

结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...

虚拟机网络不通的问题(这里以win10的问题为主,模式NAT)
当我们网关配置好了,DNS也配置好了,最后在虚拟机里还是无法访问百度的网址。 第一种情况: 我们先考虑一下,网关的IP是否和虚拟机编辑器里的IP一样不,如果不一样需要更改一下,因为我们访问百度需要从物理机…...