MySQL C API的使用
MySQL C API的使用
介绍及使用
MySQL C API(也称为 MySQL Connector/C)是用于与 MySQL 数据库交互的 C 语言 API。它提供了一组函数和结构体,允许你在 C 程序中连接到 MySQL 数据库服务器,并执行查询、插入、更新等数据库操作。
以下是 MySQL C API 的基本使用步骤:
1. 包含头文件:
在你的 C 代码中包含 MySQL C API 的头文件:
#include <mysql/mysql.h>
2. 初始化和连接:
在程序开始时,需要初始化 MySQL C API 并建立与数据库服务器的连接。以下是一个简单的例子:
// 这个函数初始化MySQL,并返回一个MYSQL指针。这个指针在后续的操作中都会使用到。
MYSQL *conn;
conn = mysql_init(NULL);if (conn == NULL) {fprintf(stderr, "mysql_init() failed\n");exit(1);
}
//连接到数据库:mysql_real_connect()使用这个函数来连接到数据库。其中参数包括上一步得到的MYSQL指针,以及数据库的主机名、用户名、密码、数据库名等。
if (mysql_real_connect(conn, "localhost", "user", "password", "database", 0, NULL, 0) == NULL) {fprintf(stderr, "mysql_real_connect() failed\n");mysql_close(conn);exit(1);
}
// 补充了解
// 最后三个参数大部分情况下为0,NULL,0即可,三个参数详细介绍如下
port:这是数据库服务端的端口号,默认是MySQL的默认端口3306。如果提供0,将使用默认端口;
unix_socket:这是Unix系统专用的,如果mysql服务器运行在本地,并使用了Unix socket,这个参数就指定了该socket的路径。对于运行在网络上的服务器,此参数通常为NULL;
client_flag:这是额外标志,通常为0。对于特殊情况,可以设置为一些特定的值,比如CLIENT_COMPRESS(在客户端和服务器间进行压缩),CLIENT_SSL(使用ssl连接),CLIENT_LOCAL_FILES(允许LOAD DATA LOCAL操作)等等。详情请查阅MySQL的官方文档。
为了兼容更多的使用场景,mysql_real_connect函数给出了很多参数,适合应对各种复杂的数据库连接情况。但是在实际使用中,大部分情况下,使用默认参数(port为0,unix_socket为NULL,client_flag为0)就足够了。
在这个例子中,使用 mysql_init 初始化 MySQL 对象,然后使用 mysql_real_connect 建立与 MySQL 服务器的连接。你需要提供主机名、用户名、密码和数据库名。
3. 执行查询:
一旦连接建立,你可以执行 SQL 查询。以下是一个简单的查询示例:
//mysql_query()使用这个函数来执行SQL查询。查询结果可以用后续的函数来获取。
if (mysql_query(conn, "SELECT * FROM your_table")) {fprintf(stderr, "SELECT query failed: %s\n", mysql_error(conn));mysql_close(conn);exit(1);
}
//获取查询结果:mysql_store_result() 或 mysql_use_result()这两个函数可以获取查询结果。mysql_store_result()将所有的查询结果存储在客户端,mysql_use_result()则允许你一个接一个地获取结果行。
MYSQL_RES *result = mysql_store_result(conn); // 注意,返回值是指针
if (result == NULL) {fprintf(stderr, "mysql_store_result() failed\n");mysql_close(conn);exit(1);
}
//遍历结果集:mysql_fetch_row()这个函数可以获取结果集中的一行。你可以在循环中使用它来遍历所有的结果行。
int num_fields = mysql_num_fields(result);
MYSQL_ROW row; //typedef char **MYSQL_ROW
while ((row = mysql_fetch_row(result))) {for (int i = 0; i < num_fields; i++) {printf("%s ", row[i] ? row[i] : "NULL");}printf("\n");
}mysql_free_result(result);// 补充了解
typedef struct MYSQL_RES {uint64_t row_count;MYSQL_FIELD *fields;struct MYSQL_DATA *data;MYSQL_ROWS *data_cursor;unsigned long *lengths; /* column lengths of current row */MYSQL *handle; /* for unbuffered reads */const struct MYSQL_METHODS *methods;MYSQL_ROW row; /* If unbuffered read */MYSQL_ROW current_row; /* buffer to current row */struct MEM_ROOT *field_alloc;unsigned int field_count, current_field;bool eof; /* Used by mysql_fetch_row *//* mysql_stmt_close() had to cancel this result */bool unbuffered_fetch_cancelled;enum enum_resultset_metadata metadata;void *extension;
} MYSQL_RES;
这个例子执行一个简单的 SELECT 查询,然后使用 mysql_store_result 获取查询结果,并使用 mysql_fetch_row 逐行读取结果集中的数据。
4. 插入、更新和删除:
你可以使用 mysql_query 函数执行插入、更新和删除等修改数据库的操作。以下是一个插入数据的示例:
if (mysql_query(conn, "INSERT INTO your_table (column1, column2) VALUES ('value1', 'value2')")) {fprintf(stderr, "INSERT query failed: %s\n", mysql_error(conn));mysql_close(conn);exit(1);
}
5. 清理结果集:
//清理结果集:mysql_free_result()当你处理完查询结果后,需要调用这个函数来清理结果集。
mysql_free_result(result);
mysql_close(conn);
6.关闭连接
在程序结束时,确保关闭与 MySQL 服务器的连接并释放资源:
mysql_close(conn);
这些是 MySQL C API 的基本用法示例。请注意,为了简洁起见,没有进行错误处理的详细检查。在实际应用中,应该更加详细地处理错误以确保程序的稳定性。
API封装
以下为个人在使用过程中,对API的进一步封装
class DataBase {public:~DataBase() {Close(); // 析构函数自动关闭数据库}// 初始化,可以指定连接的 用户名,密码,数据存储库,host,portvoid Init(string name, string pwd, string database, string host = "localhost", int port = 3306) {mysql_init(&mysql_);// 连接数据库if (mysql_real_connect(&mysql_, host.c_str(), name.c_str(), pwd.c_str(), database.c_str(), port, NULL, 0) == NULL) {cout << mysql_error(&mysql_) << endl;cout << "connect error!" << endl;exit(-1);}// 设置字符集编码,包含了character_set_connection为utf8mb4,因为库以及表采用的是utf8mb4字符集if (!mysql_set_character_set(&mysql_, "utf8mb4")){printf("New client character set: %s\n", mysql_character_set_name(&mysql_));}// 设置character_set_client 客户端字符集为GBK,因为命令行窗口是GBK编码,否则mysql 1366 error// 设置character_set_results 查询结果集为GBK,因为命令行窗口是GBK编码,要对应起来,否乱码if (!Query("set character_set_client = gbk") || !Query("set character_set_results = gbk")) {cout << "set character_set_client or character_set_results gbk error:" << Error() << endl;}}// 执行语句bool Query(const string& query) {// 成功0,失败非0return !mysql_query(&mysql_, query.c_str());}// 释放结果集void FreeResult() {mysql_free_result(res_);}// 返回记录行数int Rows() {return mysql_num_rows(res_);}// 返回字段数量int Cols() {return mysql_num_fields(res_);}// 关闭数据库void Close() {mysql_close(&mysql_);}// 获取查询结果集MYSQL_RES* GetResult() {return res_ = mysql_store_result(&mysql_);}// 获取表字段MYSQL_FIELD* GetFields() {return mysql_fetch_fields(res_);}const char* Error() {return mysql_error(&mysql_);}// 获取一行记录MYSQL_ROW FetchRow() {return row_ = mysql_fetch_row(res_);}// 不区分大小写进行比较字符串,主要用于字段名比较bool InsensistiveStringCompare(const string& str1, const string& str2) {string str1Cpy(str1);string str2Cpy(str2);transform(str1Cpy.begin(), str1Cpy.end(), str1Cpy.begin(), ::tolower);transform(str2Cpy.begin(), str2Cpy.end(), str2Cpy.begin(), ::tolower);return (str1Cpy == str2Cpy);}// 输出结果集,便于调试void Show(const string& query) {if (!Query(query)) {cout << "show test error:" << Error() << endl;exit(-1);}MYSQL_RES* res = GetResult();if (!res) {cout << "GetResult error:" << Error() << endl;exit(-1);}int n = Rows(), m = Cols();cout << "共" << n << "条记录," << m << "个字段" << endl;MYSQL_ROW row;string field;vector<vector<string>> records(n + 1, vector<string>(m));vector<int> max_len(m); // 记录每列数据的最大长度,便于格式化输出 int len = 0;MYSQL_FIELD* fields = GetFields();for (int i = 0; i < m; ++i) {records[0][i] = fields[i].name; // 获取字段名max_len[i] = (int)max(fields[i].name_length, fields[i].max_length); // 获取字段记录最大长度以及字段长度,记录最大值}for (int i = 1; i <= n; ++i) {row = FetchRow();for (int j = 0; j < m; ++j) {if (row[j]) field = row[j];else field = "NULL";records[i][j] = field;len = max(len, sizeof field);}}for (int i = 0; i <= n; ++i) {for (int j = 0; j < m; ++j) {cout << setiosflags(ios::left) << setw(max_len[j] + 2) << records[i][j] << ' ';}cout << endl;}}
private:MYSQL mysql_; // 数据库句柄MYSQL_RES* res_; // 查询结果集合MYSQL_ROW row_; // 记录结构体};
相关文章:
MySQL C API的使用
MySQL C API的使用 介绍及使用 MySQL C API(也称为 MySQL Connector/C)是用于与 MySQL 数据库交互的 C 语言 API。它提供了一组函数和结构体,允许你在 C 程序中连接到 MySQL 数据库服务器,并执行查询、插入、更新等数据库操作。…...
JavaScript防御性编程
简单聊一下防御性编程,初衷是开发人员为了防止自己被裁员,而将代码编写为只有自己能看懂。如何只有自己能看懂?方法多种多样,但不能将简单问题复杂化,比如:编写一堆无效的逻辑关系,或将业务复杂…...
微信预约小程序制作指南:从小白到专家
在当今的数字时代,微信小程序已经成为了一种非常流行的应用方式。预约功能更是成为了许多小程序的核心功能之一。如果你也想为你的小程序添加预约功能,以下步骤将会对你有所帮助。 一、进入乔拓云网后台 乔拓云网是一个在线小程序开发平台,你…...
向量数据库:Milvus
特性 Milvus由Go(63.4%),Python(17.0%),C(16.6%),Shell(1.3%)等语言开发开发,支持python,go,java接口(C,Rust,c#等语言还在开发中),支持单机、集群部署,支持CPU、GPU运算。Milvus 中的所有搜索和查询操作都在内存中执行…...
亚马逊国际商品详情 API:获取特定商品详细信息的实践
随着电子商务的飞速发展,亚马逊作为全球最大的在线零售商之一,提供了丰富的商品详情 API,使得第三方开发者能够轻松地获取亚马逊网站上的商品信息。本文将介绍如何使用亚马逊国际商品详情 API(Amazon Product Advertising API&…...
MSB30M-ASEMI小贴片整流桥MSB30M
编辑:ll MSB30M-ASEMI小贴片整流桥MSB30M 型号:MSB30M 品牌:ASEMI 封装:UMSB-4 最大平均正向电流:3A 最大重复峰值反向电压:1000V 产品引线数量:4 产品内部芯片个数:4 产品…...
Redis启动方式
redis三种启动方式 1.直接启动 进入redis根目录,执行命令: #加上‘&’号使redis以后台程序方式运行 ./redis-server & 2.通过指定配置文件启动 可以为redis服务启动指定配置文件,例如配置为/etc/redis/6379.conf 进入redis根目录&#x…...
TEMU 新手小白必看!2024入驻流程/入驻类目/入驻资料等详细流程讲解
2023 TEMU 可谓是赚足眼球,流量持续上涨,2024年相信不少卖家们已经跃跃欲试,但大陆卖家如何入驻TEMU?哪些品类适合入驻?又有哪些入驻要求和资料?别急,今天东哥就一一给大家详细讲解,…...
【C语言】数组
一维数组的创建和初始化 数组是一组相同类型元素的集合。 数组的创建 //数组的创建方式:type_t arr_name [const_n];//type_t 是指数组的元素类型//const_n 是一个常量表达式,用来指定数组的大小数组创建的实例: 数组创建ÿ…...
常见测试技术都有哪些?
测试技术是用于评估系统或组件的方法,目的是发现它是否满足给定的要求。系统测试有助于识别缺口、错误,或与实际需求不同的任何类型的缺失需求。测试技术是测试团队根据给定的需求评估已开发软件所使用的最佳实践。这些技术可以确保产品或软件的整体质量…...
Spring事务控制
1.事务介绍 1.1什么是事务? 当你需要一次执行多条SQL语句时,可以使用事务。通俗一点说,如果这几条SQL语句全部执行成功,则才对数据库进行一次更新,如果有一条SQL语句执行失败,则这几条SQL语句全部不进行执…...
swaggerUI不好用,试试这个openapiUI?
title: swaggerUI不好用,试试这个openapiUI? date: 2024-01-08 categories: [tool] tags: [openapi,工具] description: 基于swaggger2, openapi3规范的UI文档 1.背景 由于长期使用 swaggerUI 工具,它的轻量风格个人觉得还是不错的,但是它…...
嵌入式物联网项目开发实战例程-STM32F103系列之外围器件代码
开发STM32F103很好的参考例程,轻松实现各类外围器件的开发。持续更新中,欢迎关注及收藏。 0001基于STM32F103单片机GPIO实现控制LED灯闪烁的程序代码.zip 0002基于STM32F103单片机GPIO实现按键KEY的检测程序代码.zip 0003基于STM32F103单片机GPIO实现外部…...
Docker Compose--部署SpringBoot项目--实战
原文网址:Docker Compose--部署SpringBoot项目--实战-CSDN博客 简介 本文用实战介绍Docker Compose部署SpringBoot项目。 ----------------------------------------------------------------------------------------------- 分享Java真实高频面试题,…...
单电阻FOC算法实现永磁同步电机的调整步骤和设置
本文档介绍了使用 单电阻FOC 算法实现永磁同步电机(Permanent Magnet Synchronous Motor,PMSM)调整所需的步骤和设置。由于不同电机存在参数差异,因此需针对不同的电机和负载对该算法进行调整。该电机库已经在在落地扇和空净等风机…...
化学DS-1040 Tosylate 抑制剂 1335138-89-0科研用途
化合物1219962-49-8是一种小分子化合物,分子式为C15H25N3O4,相对分子质量为305.37。该化合物为白色至灰白色粉末,不溶于水,易溶于有机溶剂,如甲醇、乙醇等。 AT791是一种与细胞周期调控相关的蛋白激酶,参与…...
PaddlePaddle初使用
模型导出与预测 # -c 后面设置训练算法的yml配置文件 # -o 配置可选参数 # Global.pretrained_model 参数设置待转换的训练模型地址,不用添加文件后缀 .pdmodel,.pdopt或.pdparams。 # Global.save_inference_dir参数设置转换的模型将保存的地址。pytho…...
【FPGA】分享一些FPGA数字信号处理相关的书籍
在做FPGA工程师的这些年,买过好多书,也看过好多书,分享一下。 后续会慢慢的补充书评。 【FPGA】分享一些FPGA入门学习的书籍【FPGA】分享一些FPGA协同MATLAB开发的书籍 【FPGA】分享一些FPGA视频图像处理相关的书籍 【FPGA】分享一些FPGA高速…...
深度解析JavaScript面试热点:事件循环、上下文、箭头函数、变量作用域与ES6模块
JavaScript面试中经常涉及到事件循环、上下文、箭头函数、变量作用域以及ES6模块等核心概念。通过清晰的代码示例,我们深入讨论这些主题,揭示其中的关键细节。 事件循环(Event Loop) JavaScript开发者每天都与事件循环打交道&am…...
Javaweb之Mybatis的动态SQL的详细解析
3. Mybatis动态SQL 3.1 什么是动态SQL 在页面原型中,列表上方的条件是动态的,是可以不传递的,也可以只传递其中的1个或者2个或者全部。 而在我们刚才编写的SQL语句中,我们会看到,我们将三个条件直接写死了。 如果页面…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
【Redis技术进阶之路】「原理分析系列开篇」分析客户端和服务端网络诵信交互实现(服务端执行命令请求的过程 - 初始化服务器)
服务端执行命令请求的过程 【专栏简介】【技术大纲】【专栏目标】【目标人群】1. Redis爱好者与社区成员2. 后端开发和系统架构师3. 计算机专业的本科生及研究生 初始化服务器1. 初始化服务器状态结构初始化RedisServer变量 2. 加载相关系统配置和用户配置参数定制化配置参数案…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
ETLCloud可能遇到的问题有哪些?常见坑位解析
数据集成平台ETLCloud,主要用于支持数据的抽取(Extract)、转换(Transform)和加载(Load)过程。提供了一个简洁直观的界面,以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...
uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
计算机基础知识解析:从应用到架构的全面拆解
目录 前言 1、 计算机的应用领域:无处不在的数字助手 2、 计算机的进化史:从算盘到量子计算 3、计算机的分类:不止 “台式机和笔记本” 4、计算机的组件:硬件与软件的协同 4.1 硬件:五大核心部件 4.2 软件&#…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
