使用C语言连接MySQL

库的准备

要使用C语言连接mysql,需要使用mysql官网提供的connect库,可以去官网下载,由于我们要下载到 Linux 操作系统中,也可以使用如下指令进行安装库

sudo apt-get install libmysqlclient-dev

MySQL连接C/C++的库通常会安装在/usr/include/mysql目录下,您可以通过以下命令检查该目录下是否存在相关的头文件:

ls /usr/include/mysql

库文件通常会安装在/usr/lib/usr/lib64目录下,您可以通过以下命令检查该目录下是否存在相关的库文件:

ls /usr/lib/mysql
ls /usr/lib64/mysql

不过这只是一般的情况,根据版本的不同机器的不同都有差异,其库文件安装的位置也不同,如果安装在非标准路径下,可以使用mysql_config命令来获取正确的编译选项,从而了解到库文件安装的位置:

mysql_config --cflags --libs

我的机器是Ubuntu系统,从显示的结果我们可以看出 -L 后跟着的是 /usr/lib/x86_64-linux-gnu,说明库文件位于/usr/lib/x86_64-linux-gnu下,由于其中文件过多就不展示,实际上我们编译时也可以直接使用 -L /usr/lib

现在我们 尝试链接mysql client,通过 mysql_get_client_info() 函数,来验证我们的引入是否成功。
#include<iostream>
#include <mysql/mysql.h>
using namespace std;
int main()
{cout<< "mysql version:" << mysql_get_client_info() <<endl;
}

编译指令如下:

 g++ -o mytest testdb.cc -L /usr/lib -l mysqlclient

其中 -L 后指明了动态库的路径,-l 跟着所要链接的动态库,由于我们在包含头文件时写的是#include <mysql/mysql.h> ,所以不用再指明头文件的具体路径,因为头文件位于 /usr/include/mysql 路径下,而 /usr/include 已经添加到环境变量PATH中,如果包含头文件时写的是#include <mysql.h>,则编译时需要添加 -I /usr/include/mysql ,指明头文件所在路径。

运行结果如下,说明我们已经下载好MySQL连接C/C++的库。

mysql接口介绍

mysql_init

MYSQL *mysql_init(MYSQL *mysql);

该函数用于初始化一个MySQL连接对象。

第一个参数 MYSQL C api中一个非常重要的变量,里面内存非常丰富,有 port,dbname,charset等连接基本参数。
  • 如果mysql是NULL指针,该函数将分配、初始化、并返回新对象。
  • 如果mysql不是NULL指针,该函数将初始化对象,并返回对象的地址。
MYSQL* conn = mysql_create_conn(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的)mysql_real_connect用于尝试与运行在主机上的MySQL数据库引擎建立连接。在能够执行需要有效MySQL连接句柄结构的任何其他API函数之前,mysql_real_connect必须成功完成。

  • mysql:这应该是一个已经初始化的MYSQL结构的地址。在调用mysql_real_connect之前,必须调用mysql_init来初始化MYSQL结构。
  • host:主机名或IP地址。如果hostNULL或字符串"localhost",连接将被视为与本地主机的连接。
  • user:用户的MySQL登录ID。如果userNULL或空字符串"",用户将被视为当前用户。
  • passwd:用户的密码。
  • db:数据库名称。如果dbNULL,连接会将默认的数据库设为该值。
  • port:如果不是0,其值将用作TCP/IP连接的端口号。注意,host参数决定了连接的类型。
  • unix_socket:如果不是NULL,该字符串描述了应使用的套接字或命名管道。注意,host参数决定了连接的类型。
  • client_flag:通常为0,但也能设置为特定标志的组合,以允许特定功能,如使用压缩协议、返回发现的行数而非受影响的行数等。

我们可以先使用如下代码来查看是否连接成功,该文件为 testdb.cc

#include<iostream>
#include <mysql/mysql.h>
using namespace std;
int main()
{MYSQL* conn=mysql_init(nullptr);   if(conn==nullptr)cout<<"mysql_init error"<<endl;//链接数据库mysql_real_connect(conn,"localhost","lbk","2162627569","connect",3306,nullptr,0);if(conn==nullptr)cout<<"mysql_real_connect error"<<endl;elsecout<<"mysql_real_connect success"<<endl;return 0;
}

编译指令

g++ -o mytest testdb.cc -L /usr/lib -l mysqlclient

我们可以看到连接成功。

mysql_query

int mysql_query(MYSQL *mysql, const char *query);

参数:

  • mysql:一个已经初始化的MYSQL对象,表示与MySQL数据库的连接。
  • query:一个以空字符结尾的字符串,包含了要发送的SQL查询语句。

返回值:如果查询成功,函数返回0;如果发生错误,函数返回非零值。

例如我们向connect数据库中的stu表中插入数据

#include <iostream>
#include <mysql/mysql.h>
using namespace std;
int main()
{MYSQL *conn = mysql_init(nullptr);if (conn == nullptr)cout << "mysql_init error" << endl;// 链接数据库mysql_real_connect(conn, "localhost", "lbk", "2162627569", "connect", 3306, nullptr, 0);if (conn == nullptr)cout << "mysql_real_connect error" << endl;// 执行sql语句const char *sql = "insert into stu values(1,'Tom')";if (mysql_query(conn, sql) == 0)cout << "insert success" << endl;return 0;
}

运行程序后,我们可以在MySQL中看到stu表中插入的数据。

mysql_store_result

sql 执行完以后,如果是查询语句,我们当然还要读取数据,如果 update insert等语句,那么就看下操作成功与否即可。我们就需要使用select语句来获取查询结果: 如果mysql_query返回成功,那么我们就通过mysql_store_result这个函数来读取结果。原型如下:
MYSQL_RES *mysql_store_result(MYSQL *mysql);
该函数将查询的全部结果读取到客户端,分配一个MYSQL_RES结构,并将结果置于该结构中,如果读取结果集失败,mysql_store_result也会返回Null指针。以下是 MYSQL_RES结构体的定义:
typedef struct st_mysql_res {my_ulonglong row_count;  // 结果集的行数unsigned int field_count, current_field;  // 结果集的列数和当前列MYSQL_FIELD *fields;  // 结果集的列信息MYSQL_DATA *data;  // 结果集的数据MYSQL_ROWS *data_cursor;  // 结果集的光标MEM_ROOT field_alloc;  // 内存结构MYSQL_ROW row;  // 非缓冲的时候用到MYSQL_ROW current_row;  // mysql_store_result 时会用到,当前行unsigned long *lengths;  // 每列的长度MYSQL *handle;  // mysql_use_result 会用my_bool eof;  // 是否为行为
} MYSQL_RES;
获得了结果后,我们可以接着调用以下函数来处理结果。
my_ulonglong mysql_num_rows(MYSQL_RES *res);//获取结果行数
unsigned int mysql_num_fields(MYSQL_RES *res);//获取结果列数
mysql_fetch_fields
MYSQL_FIELD *mysql_fetch_fields(MYSQL_RES *res);//获取列的属性

MYSQL_FIELD 结构体是 MySQL C API 中用于表示查询结果集中的字段信息的结构体。它包含了字段的名称、类型、长度等元数据信息。以下是 MYSQL_FIELD 结构体的定义:

typedef struct st_mysql_field {char *name; /* 字段名 */char *org_name; /* 原始字段名,如果有别名 */char *table; /* 字段所属的表名,如果字段是表中的一个字段 */char *org_table; /* 原始表名,如果表名有别名 */char *db; /* 表所在的数据库名 */char *catalog; /* 表的目录名 */char *def; /* 字段的默认值 */unsigned long length; /* 字段的长度 */unsigned long max_length; /* 字段在结果集中的最大长度 */unsigned int name_length;unsigned int org_name_length;unsigned int table_length;unsigned int org_table_length;unsigned int db_length;unsigned int catalog_length;unsigned int def_length;unsigned int flags; /* 字段的标志 */unsigned int decimals; /* 字段的小数位数 */unsigned int charsetnr; /* 字段的字符集编号 */enum enum_field_types type; /* 字段的类型 */void *extension;
} MYSQL_FIELD;

使用案例,列出stu表的列名:

#include <iostream>
#include <mysql/mysql.h>
using namespace std;
int main()
{MYSQL *conn = mysql_init(nullptr);if (conn == nullptr)cout << "mysql_init error" << endl;// 链接数据库mysql_real_connect(conn, "localhost", "lbk", "2162627569", "connect", 3306, nullptr, 0);if (conn == nullptr)cout << "mysql_real_connect error" << endl;// 执行sql语句// const char *sql = "insert into stu values(1,'Tom')";const char *sql1 = "insert into stu values(2,'Jane')";mysql_query(conn, sql1);const char *sql2 = "insert into stu values(3,'Jake')";mysql_query(conn, sql2);const char *sql3 = "select * from stu";mysql_query(conn, sql3);MYSQL_RES *res = mysql_store_result(conn);int fnum = mysql_num_fields(res);MYSQL_FIELD *field = mysql_fetch_fields(res);for (int i = 0; i < fnum; i++){cout << field[i].name << " ";}cout << endl;return 0;
}

结果如下:

如果我们需要列的更多属性,可以按照结构体中的内容找出。
mysql_fetch_row
MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);
MYSQL_ROW结构体在 MySQL C API 中用于表示查询结果集中的一行数据。它实际上是一个指向字符串数组的指针,其中每个字符串对应结果集中的一个字段值。以下是 MYSQL_ROW 结构体的定义:
typedef char **MYSQL_ROW;

MYSQL_ROW 结构体没有显式定义的成员变量,因为它本质上是一个二级指针,指向一个字符串数组。数组中的每个元素都是一个以 null 结尾的字符串,代表结果集中的一个字段值。

mysql_close

void mysql_close(MYSQL *mysql);

mysql_close函数用于关闭与MySQL数据库的连接。这个函数是MySQL C API的一部分,通常在完成数据库操作后调用,以释放与数据库连接相关的资源。

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

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

相关文章

【Android学习】RxJava

文章目录 资料连接1. Merge & Zip操作符: 合并数据源2. Map & FlapMap & ConcatMap & Buffer: 变换操作符3. retry & retryUntil & retryWhen : 错误处理操作符4. Transformer & Compose 转换操作符5. 网络请求嵌套回调 FlatMap6. 网络请求出错重连…

Mac配置 Node镜像源的时候报错解决办法

在Mac电脑中配置国内镜像源的时候报错,提示权限问题,无法写入配置文件。本文提供解决方法,青测有效。 一、原因分析 遇到的错误是由于 .npm 目录下的文件被 root 用户所拥有,导致当前用户无法写入相关配置文件。 二、解决办法 在终端输入以下命令,输入管理员密码即可。 su…

PyTorch基础入门

目录 前言一、[张量的广播&基本运算](https://www.bilibili.com/video/BV1Gg411u7Lr/?spm_id_from333.999.0.0)1. 张量的广播特性2. 逐点&规约&比较运算 二、张量的线性代数运算1. BLAS & LAPACK2. 矩阵形变及特殊矩阵构造3. 矩阵基本运算4. 矩阵的线性代数运…

【VSCode】常用插件汇总

1 Path Autocomplete&#xff08;路径提示的插件&#xff09; 步骤一&#xff1a;在vscode的扩展搜索中直接搜索Path Autocomplete&#xff0c;直接安装 步骤二&#xff1a;配置 配置 VS Code settings.json "path-autocomplete.pathMappings": {"": &q…

IOS通过WDA自动化中遇到的问题

IOS自动化遇到的问题 搭建WDA环境中遇到的问题1、XCode unsupport iphone xxx.2、创建Bundle Identifier出现问题&#xff1a;Communication with Apple failed3、创建Bundle Identifier出现问题&#xff1a;Automatic signing failed \Signing certificate is invalid4、创建B…

(六)- DRM驱动开发(qcom)

一&#xff0c;Linux Android Display 1&#xff0c;Linux Android Display Software Subsystem 密 2&#xff0c;Linux Android Display Architecture 密 二&#xff0c;DRM/KMS Adreno DPU 1&#xff0c;硬件框图 密 1.1 Qualcomm Adreno DPU 8-Series Overview 密 …

游戏AI实现-寻路算法(GBFS)

贪婪最佳优先算法是宽度优先遍历和贪婪算法结合的产物&#xff0c;使用启发式函数选择当前最低代价的节点&#xff0c;改善了宽度优先遍历需要遍历地图的大量节点来找寻结果的缺点。 算法过程&#xff1a; 1.首先设置开始节点的启发函数值&#xff08;h&#xff09;为0&#…

[Unity]Unity跨平台开发之Android简介

Android要求和兼容 图形接口支持 注意&#xff1a; 新的 Unity 项目默认不支持 OpenGL ES 2.0。 由于硬件和图形 API 的限制&#xff0c;并非所有渲染管道都与 Android 兼容。 图片压缩 Android标准压缩格式是ETC和ASTC。Unity默认压缩格式是ASTC。如果Android设备不支持您选…

监控易在汽车制造行业信息化运维中的应用案例

引言 随着汽车制造行业的数字化转型不断深入&#xff0c;信息化类IT软硬件设备的运行状态监控、故障告警、报表报告以及网络运行状态监控等成为了企业运维管理的关键环节。监控易作为一款全面、高效的信息化运维管理工具&#xff0c;在汽车制造行业中发挥着重要作用。本文将结合…

Trimble天宝三维激光扫描仪在建筑工程竣工测量中的应用【沪敖3D】

竣工测量是建筑项目竣工阶段的一个至关重要的环节&#xff0c;它为建筑工程的质量验收和成果核查提供了核心的参考依据。传统的竣工测量方法&#xff0c;如全站仪测量&#xff0c;主要依赖于现场人工操作&#xff0c;存在一些明显的局限性&#xff0c;例如作业时间长、工作量大…

健康养生:拥抱生活的艺术

健康养生&#xff1a;拥抱生活的艺术 在快节奏的现代生活中&#xff0c;健康已成为我们最宝贵的财富。健康养生&#xff0c;不仅仅是一种生活方式的选择&#xff0c;更是一种对待生活的态度&#xff0c;它关乎于如何在日常中寻找到平衡&#xff0c;让身心得以滋养&#xff0c;…

【C语言程序设计——入门】基本数据类型与表达式(头歌实践教学平台习题)【合集】

目录&#x1f60b; <第1关&#xff1a;print 函数操作> 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果&#xff1a; <第2关&#xff1a;转义字符使用> 任务描述 相关知识 编程要求 测试说明 我的通关代码: 测试结果&#xff1a; <…

C++算法第九天

本篇文章我们继续学习c算法 目录 第一题 题目链接 题目展示 代码原理 暴力解法 二分解法 代码编写 第二题 题目链接 题目展示 代码原理 代码编写 重点回顾 朴素二分 非朴素二分 重点一 重点二 重点三 第一题 题目链接 153. 寻找旋转排序数组中的最小值 - 力…

Mysql学习笔记之SQL-2

上篇文章介绍了SQL语句的第一部分数据定义语言&#xff08;DDL)&#xff0c;这篇文章我们介绍SQL语句的第二部分&#xff0c;数据库操作语言&#xff08;DML&#xff09; 1.简介 DML全称&#xff08;Data Manipulation Language&#xff09;&#xff0c;用来对数据表中的数据…

opencv-python的简单练习

题目1.读取一张彩色图像并将其转换为灰度图。 import cv2 # 读取图片文件 img cv2.imread(./1.png)# 将原图灰度化 img_gray cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)# 输出图片 cv2.imshow(img,img) cv2.imshow(img_g,img_gray) # 进行阻塞 cv2.waitKey(0) 题目2&#xff1a;…

AOP实现操作日志记录+SQL优化器升级

文章目录 1.引入依赖1.sun-dependencies 指定依赖2.将sun-dependencies进行install3.sun-common-log引入依赖 2.sun-common-log代码实现1.LogAspect.java&#xff08;需要更改包时就修改Pointcut的切点表达式即可&#xff09;2.log4j2-spring.xml3.效果展示 3.SQL优化器升级1.目…

CH582F BLE5.3 蓝牙核心板开发板 60MHz RAM:32KB ROM:448KB

CH582F BLE5.3 蓝牙核心板开发板 60MHz RAM:32KB ROM:448KB 是一款基于南京沁恒&#xff08;WCH&#xff09;推出的高性能、低功耗无线通信芯片CH582F的开发板。以下是该开发板的功能和参数详细介绍&#xff1a; 主要特性 双模蓝牙支持&#xff1a; 支持蓝牙5.0标准&#xff0…

AI技术在演示文稿制作中的应用一键生成PPT

在快节奏的现代工作环境中&#xff0c;时间就是金钱。为了提高工作效率&#xff0c;许多专业人士都在寻找能够快速生成演示文稿&#xff08;PPT&#xff09;的工具。本文将探讨AI技术如何帮助用户自动生成演示文稿&#xff0c;从文案撰写到排版&#xff0c;最终输出成品&#x…

【Redis篇】Set和Zset 有序集合基本使用

目录 Set 基本命令 sadd SMEMBERS SISMEMBER SCARD 返回值&#xff1a; SPOP SMOVE SREM 集合间操作 交集&#xff1a; 并集&#xff1a; 差集&#xff1a; ​编辑 内部编码 使用场景&#xff1a; Zset 有序集合 Zset基本命令 ZADD ZCARD ZCOUNT ZRANGE …

安防监控Liveweb视频汇聚融合平台助力执法记录仪高效使用

Liveweb平台可接入的设备除了常见的智能分析网关与摄像头以外 &#xff0c;还可通过GB28181协议接入执法记录仪&#xff0c;实现对执法过程的全程监控与录像&#xff0c;并对执法轨迹与路径进行调阅回看。那么&#xff0c;如何做到执法记录仪高效使用呢&#xff1f; 由于执法记…