MySQL 使用 C 语言连接

在学习了 MySQL 的基础操作后,实际开发中经常需要在 C/C++ 程序中访问数据库。MySQL 官方提供了 C 语言接口库 ------ Connector/C(也称 libmysqlclient)。本文介绍如何使用该库连接 MySQL 并进行基本的查询操作。

1. 准备工作

  • 确保 MySQL 服务已启动并可正常访问。

  • 从 MySQL 官网下载对应平台的 Connector/C 库(通常包含 include/ 和 lib/ 目录)。

  • 编译时需要指定头文件路径和链接库路径。

下载得到的库结构示例:

text

复制代码
.
├── include
│   ├── mysql.h
│   └── ...
└── lib
    ├── libmysqlclient.a
    ├── libmysqlclient.so -> libmysqlclient.so.18
    └── libmysqlclient.so.18.3.0

2. 测试库是否可用

编写一个简单的程序调用 mysql_get_client_info() 获取客户端版本信息。

test.cc

cpp 复制代码
#include <stdio.h>
#include <mysql.h>

int main()
{
    printf("mysql client Version: %s\n", mysql_get_client_info());
    return 0;
}

编译命令:

bash 复制代码
gcc -o test test.c -I./include -L./lib -lmysqlclient

运行:

如果出现类似 error while loading shared libraries: libmysqlclient.so.18: cannot open shared object file 的错误,说明运行时未能找到动态库。可以通过以下方式解决:

  • 将 lib/ 目录加入 LD_LIBRARY_PATH:

    bash 复制代码
    export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH
    ./test
  • 或者将库文件复制到系统库目录(如 /usr/lib),但不推荐

3. 常用 API 介绍

3.1 初始化 ------ mysql_init()

使用库之前必须先初始化,返回一个 MYSQL* 句柄。

bash 复制代码
MYSQL *mysql_init(MYSQL *mysql);

通常传入 NULL,函数会动态分配内存。

复制代码
MYSQL *conn = mysql_init(NULL);
if (conn == NULL) {
    // 初始化失败
}

3.2 连接数据库 ------ mysql_real_connect()

复制代码
MYSQL *mysql_real_connect(MYSQL *mysql,
                          const char *host,
                          const char *user,
                          const char *password,
                          const char *db,
                          unsigned int port,
                          const char *unix_socket,
                          unsigned long clientflag);

参数说明:

参数 说明
host 主机地址,"localhost" 或 "127.0.0.1"
user 数据库用户名
password 密码
db 要连接的数据库名
port MySQL 端口,默认 3306
unix_socket 通常设为 NULL
clientflag 常设为 0

返回值:成功返回第一个参数,失败返回 NULL。

3.3 设置字符集

为避免中文乱码,连接成功后设置字符集为 UTF-8:

复制代码
mysql_set_character_set(conn, "utf8");

3.4 执行 SQL 语句 ------ mysql_query()

复制代码
int mysql_query(MYSQL *mysql, const char *q);

成功返回 0,失败返回非 0。

复制代码
if (mysql_query(conn, "SELECT * FROM student")) {
    fprintf(stderr, "Query failed: %s\n", mysql_error(conn));
}

3.5 获取查询结果 ------ mysql_store_result()

对于 SELECT 等可能返回数据的语句,执行后需要获取结果集。

复制代码
MYSQL_RES *mysql_store_result(MYSQL *mysql);

该函数返回 MYSQL_RES* 结构,保存了全部查询结果。必须记得调用 mysql_free_result() 释放内存。

3.6 解析结果集

  • 获取行数 :mysql_num_rows(res)

  • 获取列数 :mysql_num_fields(res)

  • 获取列名 :mysql_fetch_fields(res) 返回 MYSQL_FIELD* 数组

  • 获取每一行数据 :mysql_fetch_row(res) 返回 MYSQL_ROW(即 char**)

示例:

复制代码
MYSQL_RES *res = mysql_store_result(conn);
if (res == NULL) {
    fprintf(stderr, "mysql_store_result failed: %s\n", mysql_error(conn));
    return;
}

int num_fields = mysql_num_fields(res);
MYSQL_FIELD *fields = mysql_fetch_fields(res);

// 打印列名
for (int i = 0; i < num_fields; i++) {
    printf("%s\t", fields[i].name);
}
printf("\n");

// 打印数据
MYSQL_ROW row;
while ((row = mysql_fetch_row(res))) {
    for (int i = 0; i < num_fields; i++) {
        printf("%s\t", row[i] ? row[i] : "NULL");
    }
    printf("\n");
}

mysql_free_result(res);

3.7 关闭连接 ------ mysql_close()

复制代码
void mysql_close(MYSQL *sock);

释放 MYSQL* 句柄及其关联的资源。

4. 完整示例

以下示例连接本地 MySQL,查询 test_db 数据库中的 student 表,并打印结果。

复制代码
#include <stdio.h>
#include <mysql.h>

int main() {
    MYSQL *conn = mysql_init(NULL);
    if (conn == NULL) {
        fprintf(stderr, "mysql_init failed\n");
        return 1;
    }

    // 连接数据库
    if (mysql_real_connect(conn, "127.0.0.1", "root", "your_password", 
                           "test_db", 3306, NULL, 0) == NULL) {
        fprintf(stderr, "mysql_real_connect failed: %s\n", mysql_error(conn));
        mysql_close(conn);
        return 1;
    }

    // 设置字符集
    if (mysql_set_character_set(conn, "utf8")) {
        fprintf(stderr, "set charset failed: %s\n", mysql_error(conn));
    }

    // 执行查询
    if (mysql_query(conn, "SELECT id, name, age FROM student")) {
        fprintf(stderr, "query failed: %s\n", mysql_error(conn));
        mysql_close(conn);
        return 1;
    }

    // 获取结果集
    MYSQL_RES *res = mysql_store_result(conn);
    if (res == NULL) {
        fprintf(stderr, "mysql_store_result failed: %s\n", mysql_error(conn));
        mysql_close(conn);
        return 1;
    }

    // 输出列名
    int num_fields = mysql_num_fields(res);
    MYSQL_FIELD *fields = mysql_fetch_fields(res);
    for (int i = 0; i < num_fields; i++) {
        printf("%s\t", fields[i].name);
    }
    printf("\n");

    // 输出数据
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(res))) {
        for (int i = 0; i < num_fields; i++) {
            printf("%s\t", row[i] ? row[i] : "NULL");
        }
        printf("\n");
    }

    mysql_free_result(res);
    mysql_close(conn);
    return 0;
}

编译(假设头文件和库位于 ./include 和 ./lib):

复制代码
gcc -o demo demo.c -I./include -L./lib -lmysqlclient
export LD_LIBRARY_PATH=./lib:$LD_LIBRARY_PATH
./demo

5. 补充:非查询语句

对于 INSERT、UPDATE、DELETE 等不返回结果集的语句,执行 mysql_query() 后只需检查返回值,无需调用 mysql_store_result()。

复制代码
if (mysql_query(conn, "UPDATE student SET age=20 WHERE id=1")) {
    fprintf(stderr, "update failed: %s\n", mysql_error(conn));
} else {
    printf("Affected rows: %lld\n", mysql_affected_rows(conn));
}

6. 总结

  • 使用 MySQL C API 需要包含 <mysql.h>,链接 libmysqlclient。

  • 标准流程:初始化 → 连接 → 设置字符集 → 执行 SQL → 处理结果 → 释放资源 → 关闭连接。

  • 查询结果必须用 mysql_free_result() 释放,连接用 mysql_close() 关闭。

  • 错误处理通过 mysql_error(conn) 获取具体信息。

以上即使用 C 语言连接 MySQL 的基本方法,更多功能(事务、预处理语句等)可参考官方文档(mysql.com),好啦这就是关于MySQL的基础内容啦,c++后端开发掌握到这里即可,关于MySQL图形化,我推荐使用Navicat,大家可以自己找资源下载哦~~

MYSQL>>>quit;

MYSQL>>>bye;

相关推荐
2401_896732132 小时前
MySQL小笔记
mysql
程序员清风3 小时前
数据处理脚本工程化:日志、配置、命令行与测试
服务器·开发语言·数据库
学长毕设3 小时前
基于SpringBoot的青少年编程学习平台系统-附源码
spring boot·学习·青少年编程
readhere4 小时前
从ZYNQ7000开发板,学会启动嵌入式Linux系统——入门学习:EBAZ4205篇目录
linux·启动·嵌入式linux·zynq7000·ebaz4205
正在走向自律4 小时前
数据集成产品的技术底座:从日志解析原理到 KFS 同步链路搭建(含建表与增删改查完整代码)
数据库·oracle·信创·数据集成·国产数据库·kingbasees·全量+增量同步
程序员塔塔喵4 小时前
【MySQL篇|第七篇】MySQL事务
数据库·mysql·mysql事务
独隅5 小时前
Claude API 实战教程:从入门到完整项目
android·java·数据库·claude·claude code
打工仔折腾 AI5 小时前
在 Ubuntu ARM64 部署 Q1 V3.0 MuJoCo 模型:加载、单步推理与执行器响应解析
linux·运维·人工智能·python·深度学习·ubuntu·性能优化
_孤傲_5 小时前
快速掌握 MySQL 语法
数据库·后端·mysql
‎ദ്ദിᵔ.˛.ᵔ₎5 小时前
关于Linux 线程局部存储的认识
linux·运维