当前位置: 首页 > article >正文

MySQL C API高效编程:C语言实现数据库操作的深入解析

知识点【MySQL C API】

1、头文件及MYSQL * 句柄

//头文件
#include <mysql/mysql.h>

1、MYSQL

MYSQL是一个结构体,封装了与数据库连接相关的所有状态,配置和数据。

2、MYSQL *的本质

类似于 FILE*,代表一个与数据库连接的通道,所有对数据库的操作都依赖于这个句柄

每个MYSQL* 句柄都对应一个独立的数据库连接,不能在多线程间共享每个线程创建独立的句柄

3、生命周期

从 init 到 close

4、MYSQL结构体内部管理的内容

大致了解就可以 无需刻意背诵

5、MYSQL *作用

一个程序可以同时连接多个MySQL服务器,每个连接需要独立的MYSQL *句柄区分操作目标。

2、mysql_init()

**MYSQL *mysql_init(MYSQL *mysql)**

函数功能

初始化一个MYSQL对象,用于后续数据库连接操作

参数

mysql:指向MYSQL结构体的指针。

如果传入NULL,系统会自动分配并返回一个新对象。

返回值

成功:返回初始化后的MYSQL * 句柄

失败:NULL(如内存不足)

3、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服务器的实际连接

参数

mysql:有mysql_init初始化的MYSQL对象

host:主机名或者IP地址,如果是NULL,”localhost“,”127.0.0.1”被视为与本地主机连接

user:登陆用户名

passwd:登陆密码

db:默认连接的数据库名(可选)

port:服务器端口号(0表示默认端口3306)

unix_socket:套接字或命名管道(通常为NULL)

client_flag:连接标志

返回值

成功:返回传入的MYSQL *句柄

失败:NULL,可通过mysql_error(mysql)获取错误信息。

4、mysql_real_query()

**int mysql_real_query(MYSQL *mysql, const char *stmt_str, unsigned long length)**

函数功能

执行SQL查询(支持二进制数据)

参数

mysql:已连接的 MYSQL 对象

stmt_str:SQL语句字符串(不要以;结尾

length:语句长度(使用strlen(stmt_str)计算)

返回值

成功:0

失败:返回非0值,需要用mysql_error(mysql)检查错误

5、mysql_store_result()

**MYSQL_RES *mysql_store_result(MYSQL *mysql)**

函数功能

从服务器获取完整的查询结果集并存储到客户端内存

参数

mysql:已成功执行查询的MYSQL对象

返回值

成功:MYSQL_RES结果集指针

失败:返回NULL,使用mysql_error(mysql)检错

补充

适用于小型结果集,需要手动调用mysql_free_result()释放内存。

6、mysql_num_fields()

**unsigned int mysql_num_fields(MYSQL_RES *result)**

函数功能

获取结果集中的列数

参数

result:mysql_store_result 或者 mysql_use_result 返回的结果集

返回值

列数

7、mysql_num_rows()

**my_ulonglong mysql_num_rows(MYSQL_RES *result)**

函数功能

获取结果集中的行数(仅对 mysql_store_result 有效)

参数

result:my_result_result 返回的结果集

返回值

行数

补充

如果使用 mysql_use_result 需要遍历所有行才能得到准确行数

8、mysql_fetch_field()

**MYSQL_FIELD *mysql_fetch_field(MYSQL_RES *result)**

函数功能

获取结果集中 列的元数据(列名,类型,长度等)

参数

return:结果集指针

返回值

成功:返回MYSQL_FIELD结构体指针

失败:无更多列:NULL

补充

内部会自动指向下一列,无需手动操作

MYSQL_FIELD结构体

typedef struct st_mysql_field
{char *name;// 列名(如 "id")char *org_name;// 原始列名(若使用别名时)char *table;// 所属表名char *org_table;// 原始表名(若使用别名时)char *db;// 所属数据库名char *catalog;// 目录名(通常为空)char *def;// 列的默认值unsigned long length;// 列的定义长度(如 VARCHAR(255) → 255)unsigned long max_length;// 结果集中实际最大长度(需调用 mysql_store_result 后有效)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;// 列的标志(如 NOT_NULL_FLAG)unsigned int decimals;// 小数位数(如 DECIMAL(10,2) → 2)unsigned int charsetnr;// 字符集编号enum enum_field_types type;// 列的数据类型(如 MYSQL_TYPE_INT、MYSQL_TYPE_STRING)
} MYSQL_FIELD;

9、mysql_fetch_row()

**MYSQL_ROW mysql_fetch_row(MYSQL_RES *result)**
typedef char **MYSQL_ROW; *// 例如:row[0] 是第一列的值*

函数功能

从结果集中逐行获取数据

参数

result:结果集指针

返回值

成功:返回MYSQL_ROW类型(字符串数组)

失败:无更多行,NULL

补充

内部会自动指向下一行,无需手动操作

10、mysql_free_result()

**void mysql_free_result(MYSQL_RES *result)**

函数功能

释放mysql_store_result 分配的 结果集的内存

参数

result:带释放的结果集指针

返回值

11、mysql_close()

**void mysql_close(MYSQL *mysql)**

函数功能

关闭数据库连接,并释放MYSQL对象内存

参数

mysql:已连接的MYSQL

返回值

补充

不能重复关闭句柄

可以加上防二次关闭的逻辑

if(mysql != NULL )
{mysql_close(mysql);mysql = NULL;
}

自动清理未释放的结果集:

如果忘记调用mysql_free_result(),mysql_close()会隐式释放结果集,但是显示释放更加直观,更加安全。

综合案例

1、函数补充 mysql_set_character_set

int mysql_set_character_set(MYSQL *mysql, const char *csname);

函数功能

设置 MySQL 客户端连接(MYSQL* 句柄)的字符集,确保客户端与服务器之间的数据传输使用指定编码

参数

mysql:已成功连接的MYSQL *句柄

csname:字符集名称字符串

  • "utf8mb4":支持 Unicode 4 字节字符(如 Emoji)。
  • "gbk":中文编码。
  • "binary":二进制数据。

返回值

成功:0

失败:非0

****以下是不进行编码指定的,向数据库中插入中文(小明)的现象。

2、编译要求

最后需要加上 -lmysqlclient

类似于 我们在线程中添加的-lpthread

l是library(库)的意思

注意

mysql_store_result() 的作用是获取 上一个查询 的结果集。

代码展示

#include <mysql/mysql.h>
#include <stdio.h>
#include <string.h>int main(int argc, char const *argv[])
{//初始化MYSQL * conn = mysql_init(NULL);//错误1 这里参数应是NULLif(conn == NULL){perror("mysql_init");exit(1);}//连接数据库if(!mysql_real_connect(conn,NULL,"root","","person",3306,NULL,0)){fprintf(stderr,"%s\\n",mysql_error(conn));if(conn != NULL){mysql_close(conn);conn = NULL;}exit(1);}mysql_set_character_set(conn, "utf8mb4");//请求char *arr_query1 = "select num,name from new_stu";char *arr_query2 = "insert into new_stu values(109,'小明',18)";unsigned len_query1 = strlen(arr_query1);unsigned len_query2 = strlen(arr_query2);if(mysql_real_query(conn,arr_query1,len_query1)){fprintf(stderr,"%s\\n",mysql_error(conn));if(conn != NULL){mysql_close(conn);conn = NULL;}exit(1);}//获取数据集MYSQL_RES * result = NULL; if(!(result = mysql_store_result(conn))){fprintf(stderr,"%s\\n",mysql_error(conn));if(conn != NULL){mysql_close(conn);conn = NULL;}exit(1);}//遍历数据库行数 列数unsigned int len_column = mysql_num_fields(result);my_ulonglong len_row = mysql_num_rows(result);printf("column == %u,row == %llu\\n",len_column,len_row);//遍历数据库的数据if(len_row != 0){//遍历列的属性MYSQL_FIELD *filed = NULL;while(filed = mysql_fetch_field(result)){printf("%-10s",filed->name);}printf("\\n");//遍历行数据MYSQL_ROW row = NULL;while(row = mysql_fetch_row(result)){for (size_t i = 0; i < len_column; i++){printf("%-10s",row[i]);}printf("\\n");}}else{//无数据printf("No data on database!\\n");}//注意这里 这里我们在这里插入 而不是紧跟着mysql_real_query(conn,arr_query1,len_query1)插入//让大家更好地理解 结果集的存在 和 mysql_store_result 的逻辑if(mysql_real_query(conn,arr_query2,len_query2)){fprintf(stderr,"%s\\n",mysql_error(conn));if(conn != NULL){mysql_close(conn);conn = NULL;}exit(1);}//关闭数据集mysql_free_result(result);//关闭句柄if(conn != NULL){mysql_close(conn);conn = NULL;}return 0;
}

代码犯错:

1、mysql_init 参数应是NULL,写成 还未初始化的conn

2、没有加字符格式矫正,导致数据库中文乱码

mysql_set_character_set

3、对结果集的理解有误 导致mysql_store_result

以及后续result的使用上 与理想情况出现偏差。复习时重点回想

结束

代码重在练习!

代码重在练习!

代码重在练习!

今天的分享就到此结束了,希望对你有所帮助,如果你喜欢我的分享,请点赞收藏加关注,谢谢大家!!!

相关文章:

MySQL C API高效编程:C语言实现数据库操作的深入解析

知识点【MySQL C API】 1、头文件及MYSQL * 句柄 //头文件 #include <mysql/mysql.h>1、MYSQL MYSQL是一个结构体&#xff0c;封装了与数据库连接相关的所有状态&#xff0c;配置和数据。 2、MYSQL *的本质 类似于 FILE*&#xff0c;代表一个与数据库连接的通道&…...

MySQL初阶:数据库约束和表的设计

数据库约束 数据库约束是针对数据库中的表中的数据进行施加规则和条件&#xff0c;用于确保数据的准确性和可靠性。 数据库约束类型 1&#xff09;not null 非空类型 &#xff1a;指定非空类型的列不能存储null&#xff0c;如果插入的数据是null便会报错。 2&#xff09;de…...

LeetCode 解题思路 47(最长回文子串、最长公共子序列)

解题思路&#xff1a; dp 数组的含义&#xff1a; dp[i][j] 是否为回文子串。递推公式&#xff1a; dp[i][j] s.charAt(i) s.charAt(j) && dp[i 1][j - 1]。dp 数组初始化&#xff1a; 单字符 dp[i][i] true&#xff0c;双字符 dp[i][i 1] s.charAt(i) s.charA…...

左支座加工工艺与钻φ25孔专用夹具设计

1 零件结构与工艺分析 1.1 零件结构特征 本左支座为典型箱体类零件&#xff0c;采用HT200灰铸铁铸造毛坯。主体结构包含&#xff1a; 20015080mm安装基面 2φ12定位孔&#xff08;公差H7&#xff09; φ250.02主轴承孔&#xff08;表面粗糙度Ra1.6&#xff09; 4M10螺纹安…...

基于Qwen-14b的基础RAG实现及反思

1、概览 本文主要介绍RAG的基础实现过程&#xff0c;给初学者提供一些帮助&#xff0c;RAG即检索增强生成&#xff0c;主要是两个步骤&#xff1a;检索、生成&#xff0c;下面将基于这两部分进行介绍。 2、检索 检索的主要目的是在自定义的知识库kb中查询到与问题query相关的候…...

嵌入式培训之C语言学习完(十七)结构体、共用体、枚举、typedef关键字与位运算

目录 一、结构体&#xff08;struct关键字&#xff09; &#xff08;一&#xff09;声明一个结构体数据类型 &#xff08;二&#xff09;结构体的成员初始化与赋值 a、结构体变量赋值 b、结构体成员初始化 c、结构体的定义形式 &#xff08;三&#xff09;考点&#xff…...

极狐GitLab 命名空间的类型有哪些?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 命名空间 命名空间在极狐GitLab 中组织项目。因为每一个命名空间都是单独的&#xff0c;您可以在多个命名空间中使用相同的项…...

N6715C 基础型定制配置直流电源分析仪

N6715C 基础型定制配置直流电源分析仪 综述 N6715C 是一款可定制的直流电源分析仪系统&#xff0c;在装运之前已经过全面测试并组装完毕。 每台 N6715C 包括一个 N6705C 主机和 1 至 4 个模块。 模块作为 E6715C 的选件订购。 主要特点 ◆ ◆ 4 插槽主机最多可安装 4 个模块…...

4.1【LLaMA-Factory 实战】医疗领域大模型:从数据到部署的全流程实践

【LLaMA-Factory实战】医疗领域大模型&#xff1a;从数据到部署的全流程实践 一、引言 在医疗AI领域&#xff0c;构建专业的疾病诊断助手需要解决数据稀缺、知识专业性强、安全合规等多重挑战。本文基于LLaMA-Factory框架&#xff0c;详细介绍如何从0到1打造一个垂直领域的医…...

《软件项目经济性论证报告模板:全面解析与策略建议》

《软件项目经济性论证报告模板:全面解析与策略建议》 一、引言 1.1 项目背景阐述 在数字化浪潮席卷全球的当下,各行业对软件的依赖程度日益加深。[行业名称] 行业也不例外,随着业务规模的不断扩张、业务复杂度的持续提升以及市场竞争的愈发激烈,对高效、智能、定制化软件…...

腾讯云:数字世界的“量子熔炉”与硅基文明引擎​

​​一、算力拓扑学&#xff1a;重新定义空间的计算密度​​ 腾讯云的算力网络正在突破经典物理限制&#xff0c;其分布式架构通过“量子化”资源调度实现超维计算&#xff1a; ​​虚拟化跃迁​​&#xff1a;基于KVM的轻量级虚拟化技术&#xff0c;将单台物理服务器切割为百…...

Android 项目中配置了多个 maven 仓库,但依赖还是下载失败,除了使用代理,还有其他方法吗?

文章目录 前言解决方案gradlemaven 仓库 前言 我们在Android 开发的过程中&#xff0c;经常会遇到三方依赖下载不下来的问题。一般情况下我们会在项目的build.gradle文件中配置多个 maven 仓库来解决。 // Top-level build file where you can add configuration options com…...

关税冲击下,FBA国际物流企业如何靠智能拓客跑出增长“加速度”?

国际物流行业正迎来前所未有的增长机遇。据中研普华最新报告&#xff0c;2025年全球物流市场规模已突破6.27万亿美元&#xff0c;其中中国跨境物流市场预计达2.71万亿元。在全球化与数字化双轮驱动下&#xff0c;国际物流从“规模扩张”迈向“价值重构”。可以说&#xff0c;国…...

vue源代码采用的设计模式分解

No.大剑师精品GIS教程推荐0地图渲染基础- 【WebGL 教程】 - 【Canvas 教程】 - 【SVG 教程】 1Openlayers 【入门教程】 - 【源代码示例 300】 2Leaflet 【入门教程】 - 【源代码图文示例 150】 3MapboxGL【入门教程】 - 【源代码图文示例150】 4Cesium 【入门教程】…...

【java反射修改注解属性】java 通过反射,动态修改注解的某个属性值

有些情况为了偷懒&#xff0c;往往会使用注解来动态处理一些功能&#xff0c;比如Excel的导入以及导出等。但是一些情况下我们需要动态的修改注解的属性值&#xff0c;来完成一些特定场景的业务需求。 java动态修改注解的属性代码 public void updateFieldAnnotationVal(String…...

使用 JavaScript 实现数据导出为 Excel 和 CSV 文件

在 Web 开发中&#xff0c;经常会遇到需要将数据导出为文件的需求&#xff0c;例如将数据导出为 Excel 或 CSV 文件。今天&#xff0c;我们就来探讨如何使用 JavaScript 实现这一功能。 一、实现思路 我们通过 HTML 创建一个按钮&#xff0c;点击按钮时&#xff0c;触发 Java…...

eNSP中路由器RIP协议配置完整实验实验和命令解释

一、实验拓扑 二、配置命令 R1配置并先测试一下连通性 R1、R2和R3接口配置完后再测试连通性&#xff0c;直连路由可通 启动RIP进程&#xff0c;宣告直连网络 查看路由表&#xff0c;测试连通性 环回接口配置 三、命令解释及注意事项 配置命令逐行解释 system-view: 从用户视…...

密码学--AES

一、实验目的 1、完成AES算法中1轮加密和解密操作 2、掌握AES的4个基本处理步骤 3、理解对称加密算法的“对称”思想 二、实验内容 1、题目内容描述 &#xff08;1&#xff09;利用C语言实现字节代换和逆向字节代换&#xff0c;字节查S盒代换 &#xff08;2&#xff09;利…...

Vue项目中实现自定义连线图

需求描述 在vue项目中实现由自定义块元素组成的连线图。效果图 实现思路 Leader-Line 是一个用于 Web 的轻量级 JavaScript 库&#xff0c;专为创建从一个元素指向另一个元素的引导线而设计。它提供了高度自定义的能力&#xff0c;使得开发者能够轻松地在网页上实现各种指引用…...

linux中的日志分割

1.问题背景&#xff0c;nginx日志过大不好删除 [rootlocalhost cron.daily]# cd /lk/nginx/log/ [rootlocalhost log]# ll 总用量 2386188 -rw-r--r--. 1 root root 2078699697 5月 9 13:02 access.log -rw-r--r--. 1 root root 11138 5月 6 10:28 error.log [rootloc…...

C++编程语言:标准库:标准库概观(Bjarne Stroustrup)

第30章 标准库概观(Standard-Library Overview) 目录 30.1 引言 30.1.1 标准库设施 30.1.2 设计约束 30.1.3 描述风格 30.2 头文件 30.3 语言支持 30.3.1 对initializer_list的支持 30.3.2 对范围for的支持 30.4 异常处理 30.4.1 异常 30.4.1…...

独立自主的网络浏览器——Ladybird

独立自主的网络浏览器——Ladybird 随着互联网技术的飞速发展&#xff0c;浏览器作为人们探索网络世界的窗口&#xff0c;其技术创新和安全措施至关重要。然而&#xff0c;市场上绝大多数浏览器都是基于现有的成熟引擎进行开发&#xff0c;如何创新突破&#xff0c;成为一个独…...

Shiro(八):JWT介绍

1、什么是JWT&#xff1f; JWT&#xff08;JSON Web Token&#xff0c;JSON Web令牌&#xff09;是一种开放标准&#xff08;RFC 7519&#xff09;&#xff0c;用于在网络应 用环境间安全地传递声明&#xff08;claims&#xff09;作为JSON对象&#xff1b;JWT会按指定的加密算…...

【HDLBits刷题】Verilog Language——1.Basics

目录 一、题目与题解 1.Simple wire&#xff08;简单导线&#xff09; 2.Four wires&#xff08;4线&#xff09; 3.Inverter&#xff08;逆变器&#xff08;非门&#xff09;&#xff09; 4.AND gate &#xff08;与门&#xff09; 5. NOR gate &#xff08;或非门&am…...

SCDN是什么?

SCDN是安全内容分发网络的简称&#xff0c;它在传统内容分发网络&#xff08;CDN&#xff09;的基础上&#xff0c;集成了安全防护能力&#xff0c;旨在同时提升内容传输速度和网络安全性。 SCDN的核心功能有&#xff1a; DDoS防御&#xff1a;识别并抵御大规模分布式拒绝服务…...

Python 常用内置函数详解(十):help()函数——查看对象的帮助信息

目录 一、语法参考二、示例 一、语法参考 help() 函数的语法格式如下&#xff1a; 参数说明&#xff1a; request&#xff1a;可选参数&#xff0c;要查看其帮助信息的对象&#xff0c;如类、函数、模块、数据类型等&#xff1b;返回值&#xff1a;返回对象的帮助信息。 二…...

【Python系列】Python 中的 HTTP 请求处理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

辉芒微离线烧录器“文件格式错误”问题解决

最近在使用辉芒微离线烧录器烧录程序时&#xff0c;提示“文件格式错误”&#xff0c;记录一下解决方法。 一、问题现象 经过多次尝试和排查&#xff0c;发现以下几种情况&#xff1a; 情况一&#xff1a;使用离线烧录器导入固件1&#xff08;boot程序&#xff09;&#xff0c…...

buck和boost总结

目录 1. 基本概念与原理 2. 工作模式 3. 典型应用场景 4. Buck-Boost电路&#xff1a;升降压结合 5. 核心区别与选择 1. 基本概念与原理 Buck电路&#xff08;降压电路&#xff09; 通过开关器件&#xff08;如MOSFET&#xff09;周期性地导通和关断&#xff0c;控制电感充…...

Ansible内置模块之package

原创&#xff1a;厦门微思网络 Ansible内置模块之 package ansible.builtin.package 模块用于管理基于 Linux 系统上的软件包。它是一个通用模块&#xff0c;支持多个包管理器&#xff08;如 apt、yum、dnf、zypper 等&#xff09;&#xff0c;可以安装、更新和删除软件包。其…...