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

14.MySQL使用C语言连接

14.MySQL使用C语言连接

文章目录

  1. 引入库
  2. 下载库文件
  3. 在项目中使用库
  4. 使用库
    • 连接数据库
      • 创建MySQL对象
      • 连接数据库
      • 关闭数据库连接
      • 连接示例
    • 下发SQL请求
      • 设置编码格式
    • 测试表介绍
    • 向数据库中插入数据
    • 删除数据库中的数据
    • 修改数据库中的数据
    • 获取查询结果
      • 获取查询结果的行数
      • 获取查询结果的列数
      • 获取查询结果的列属性
      • 获取查询结果中的一行数据
      • 查询示例

引入库

要使用C语言连接MySQL数据库,首先需要引入MySQL官方提供的开发库。这个库中包含了我们进行数据库操作所需要的各种头文件和动态链接库。通过这些资源,我们可以编写出能够与MySQL服务器进行通信的C程序。

在开始之前,确保你已经下载了适合你操作系统版本的MySQL Connector/C库。如果你是在Linux环境下工作,可以从MySQL官网下载对应的压缩包,并将其上传到你的云服务器上。例如,可以将下载的库文件存放在一个名为thirdPath的目录下,以便后续管理和使用。

上传完成后,使用rz -E命令将文件上传到服务器,接着利用tar命令解压压缩包。为了方便后续的操作,建议将解压后的目录名称简化,这样在项目中引用时会更加直观。

进入解压后的目录后,你会看到两个重要的子目录:includelib。其中,include目录下存放的是各种头文件,而lib目录下则是静态库和动态库文件。这些文件是我们在编写C语言程序时不可或缺的部分。

在项目中使用库

为了更方便地在项目中使用这些库文件,可以在项目目录下创建两个软链接,分别指向includelib目录。这样一来,你就可以直接在项目目录下访问到所需的头文件和库文件。

接下来,我们可以通过调用mysql_get_client_info函数来验证库是否成功引入。该函数的作用是获取客户端的版本信息。以下是一个简单的示例代码:

#include <stdio.h>
#include <mysql.h>int main() {printf("MySQL client version: %s\n", mysql_get_client_info());return 0;
}

为了让编译过程更加便捷,建议在项目目录下创建一个Makefile。Makefile中的内容如下所示:

CC = gcc
CFLAGS = -Wall -I./include
LDFLAGS = -L./lib -lmysqlclientall: mainmain: main.o$(CC) $(CFLAGS) main.o $(LDFLAGS) -o mainmain.o: main.c$(CC) $(CFLAGS) -c main.cclean:rm -f *.o main

在这个Makefile中,-I用于指定头文件的搜索路径,-L用于指定库文件的搜索路径,而-l则用于指明需要链接的库文件名称。

完成Makefile的编写后,通过make命令即可编译生成可执行程序。然而,此时生成的可执行程序还不能直接运行,因为系统默认的动态库搜索路径中没有包含我们使用的mysqlclient库。

解决这个问题的方法有几种:

  1. 将库文件拷贝到系统默认的库文件搜索路径 /lib64
  2. 将库文件所在的目录路径添加到 LD_LIBRARY_PATH 环境变量中。
  3. 将库文件所在的目录路径保存到以.conf为后缀的配置文件中,然后将该文件拷贝到 /etc/ld.so.conf.d/ 目录下,并使用ldconfig命令对配置文件进行更新。

在这里,我们选择第三种方法。具体步骤如下:

  1. 创建一个新的配置文件,比如mysql.conf
  2. 将库文件所在的目录路径写入该配置文件中。
  3. mysql.conf文件复制到/etc/ld.so.conf.d/目录下。
  4. 运行ldconfig命令更新动态链接库缓存。

完成上述步骤后,再次运行生成的可执行程序,你应该能看到客户端的版本信息,这表明库已经成功引入。

使用库

创建MySQL对象

在连接数据库之前,首先需要创建一个MySQL对象。这个对象将用于与MySQL服务器进行交互。创建MySQL对象的函数如下:

MYSQL* mysql_init(MYSQL *mysql);

该函数用于分配或初始化一个MySQL对象。如果传入的参数是NULL,函数会自动为你分配一个MySQL对象并返回;如果传入的参数是一个地址,函数将在该地址处帮你完成初始化。

连接数据库

创建完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 clientflag);

参数说明:

  • mysql:表示在连接数据库前调用mysql_init函数创建的MySQL对象。
  • host:表示需要连接的MySQL服务器的IP地址。
  • user:表示连接MySQL服务器时所使用用户的用户名。
  • passwd:表示连接MySQL服务器时所使用用户的密码。
  • db:表示连接MySQL服务器后需要使用的数据库。
  • port:表示连接的MySQL服务器所对应的端口号。
  • unix_socket:表示连接时应该使用的套接字或命名管道,通常设置为NULL
  • clientflag:可以设置为多个标志位的组合,表示允许特定的功能,通常设置为0。

关闭数据库连接的函数如下:

void mysql_close(MYSQL *sock);

示例代码

下面是一个完整的示例代码,展示了如何连接数据库:

#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、创建MySQL对象MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 3、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}

下发SQL请求

连接数据库后,就可以向MySQL服务器下发SQL请求了。下发SQL请求的函数如下:

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

参数说明:

  • mysql:表示在连接数据库前调用mysql_init函数创建的MySQL对象。
  • q:表示向MySQL服务器下发的SQL请求。

在连接数据库之后,还需要设置编码格式,以避免数据交互过程中出现乱码。设置编码格式的函数如下:

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

参数说明:

  • mysql:表示在连接数据库前调用mysql_init函数创建的MySQL对象。
  • csname:表示要设置的编码格式,如"utf8"

测试表介绍

在与MySQL数据库交互时,假设我们有一个名为connect_demon的数据库,其中包含一个user表。表中有三条记录,分别是用户的信息。

向数据库中插入数据

在调用mysql_query函数时,向MySQL服务器下发一条INSERT SQL语句。例如:

#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、创建MySQL对象MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 设置编码格式mysql_set_character_set(ms, "utf8");// 3、向数据库表中插入记录const char sql[] = "INSERT INTO user (id, name, age) VALUES (4, '赵六', 25)";if (mysql_query(ms, sql) != 0) {printf("插入数据失败! %s\n", mysql_error(ms));return 2;}printf("插入数据成功!\n");// 4、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}

删除数据库中的数据

同样地,调用mysql_query函数并向MySQL服务器下发一条DELETE SQL语句。例如:

#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、创建MySQL对象MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 设置编码格式mysql_set_character_set(ms, "utf8");// 3、删除数据库表中的记录const char sql[] = "DELETE FROM user WHERE id=4";if (mysql_query(ms, sql) != 0) {printf("删除数据失败! %s\n", mysql_error(ms));return 2;}printf("删除数据成功!\n");// 4、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}

修改数据库中的数据

调用mysql_query函数并向MySQL服务器下发一条UPDATE SQL语句。例如:

#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、创建MySQL对象MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 设置编码格式mysql_set_character_set(ms, "utf8");// 3、修改数据库表中的记录const char sql[] = "UPDATE user SET age=22 WHERE id=1";if (mysql_query(ms, sql) != 0) {printf("修改数据失败! %s\n", mysql_error(ms));return 2;}printf("修改数据成功!\n");// 4、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}

获取查询结果

对于数据库中的数据进行增删改操作时,只需要调用mysql_query向服务器下发对应的SQL请求。而对于查询操作,则需要额外获取查询结果。

获取查询结果的函数如下:

MYSQL_RES* mysql_store_result(MYSQL *mysql);

该函数会调用指定MySQL对象中对应的函数指针来获取查询结果,并将获取到的查询结果保存到MYSQL_RES变量中进行返回。需要注意的是,MYSQL_RES变量的内存空间是通过malloc分配的,因此在使用完后需要调用free函数进行释放,否则会造成内存泄漏。

获取查询结果的行数和列数

获取查询结果的行数和列数的函数如下:

my_ulonglong mysql_num_rows(MYSQL_RES *res);
unsigned int mysql_num_fields(MYSQL_RES *res);

获取查询结果的列属性

获取查询结果的列属性的函数如下:

MYSQL_FIELD* mysql_fetch_fields(MYSQL_RES *res);

获取查询结果中的一行数据

获取查询结果中的一行数据的函数如下:

MYSQL_ROW mysql_fetch_row(MYSQL_RES *result);

查询示例

下面是一个完整的查询示例,展示如何查询user表中的数据并进行打印输出:

#include <stdio.h>
#include <string.h>
#include <mysql.h>const char host[] = "127.0.0.1";
const char user[] = "root";
const char passwd[] = "password";
const char db[] = "test_db";
const int port = 3306;int main() {// 1、获取MySQL实例MYSQL* ms = mysql_init(NULL);// 2、连接数据库if (mysql_real_connect(ms, host, user, passwd, db, port, NULL, 0) == NULL) {fprintf(stderr, "数据库连接失败! %s\n", mysql_error(ms));return 1;}printf("数据库连接成功!\n");// 设置编码格式mysql_set_character_set(ms, "utf8");// 3、查询数据库表中的记录const char sql[] = "SELECT * FROM user";if (mysql_query(ms, sql) != 0) {printf("查询数据失败! %s\n", mysql_error(ms));return 2;}printf("查询数据成功!\n");// 获取查询结果MYSQL_RES* res = mysql_store_result(ms);int rows = mysql_num_rows(res); // 数据的行数int cols = mysql_num_fields(res); // 数据的列数// 获取每列的属性并打印列名MYSQL_FIELD* fields = mysql_fetch_fields(res);for (int i = 0; i < cols; i++) {printf("%s\t", fields[i].name);}printf("\n");for (int i = 0; i < rows; i++) {// 获取一行数据并进行打印MYSQL_ROW row = mysql_fetch_row(res);for (int j = 0; j < cols; j++) {printf("%s\t", row[j]);}printf("\n");}// 释放内存空间free(res);// 4、关闭数据库mysql_close(ms);printf("数据库关闭成功!\n");return 0;
}
http://www.lqws.cn/news/199567.html

相关文章:

  • SpringBoot项目接口集中测试方法及实现
  • 【基础算法】枚举(普通枚举、二进制枚举)
  • RAG检索系统的两大核心利器——Embedding模型和Rerank模型
  • 策略模式实战:Spring中动态选择商品处理策略的实现
  • 《真假信号》速读笔记
  • 物联网协议之MQTT(二)服务端
  • 轮廓 填充空洞 删除孤立
  • 【Dv3Admin】系统视图字典管理API文件解析
  • 靶场(二十)---靶场体会小白心得 ---jacko
  • 探索C++标准模板库(STL):String接口的底层实现(下篇)
  • JavaScript ES6 解构:优雅提取数据的艺术
  • 【python与生活】如何构建一个解读IPO招股书的算法?
  • 虚幻基础:角色旋转
  • 【HarmonyOS Next之旅】DevEco Studio使用指南(三十一) -> 同步云端代码至DevEco Studio工程
  • VBA之Word应用第三章第十节:文档Document对象的方法(三)
  • 华为云Astro中服务编排、自定义模型,页面表格之间有什么关系?如何连接起来?如何操作?
  • 巴西医疗巨头尤迈Kafka数据泄露事件的全过程分析与AI安防策略分析
  • 食品计算—Food Portion Estimation via 3D Object Scaling
  • Pnpm的使用
  • 零基础在实践中学习网络安全-皮卡丘靶场(第十五期-URL重定向模块)
  • LBE-LEX系列工业语音播放器|预警播报器|喇叭蜂鸣器的上位机配置操作说明
  • Python爬虫实战:研究Unirest库相关技术
  • VNA校准基础知识
  • Mac版Visual Studio Code Copilot 无法使用的解决方法
  • Linux(生产消费者模型/线程池)
  • 数据库管理-第334期 Oracle Database 23ai测试版RAC部署文档(20250607)
  • MVC分层架构模式深入剖析
  • AI驱动的B端页面革命:智能布局、数据洞察的底层技术解析
  • JAVA国际版二手交易系统手机回收好物回收发布闲置商品系统源码支持APP+H5
  • C++--list的使用及其模拟实现