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;

相关推荐
海绵宝宝转agent1 小时前
learn-claude-code第1-5章开源学习笔记分享
人工智能·笔记·python·学习
Ruiery1 小时前
Linux 6.6内核 CPU 深度解析(七):调度器启动 — 从单核到多核,调度器分阶段点亮
linux·运维·服务器
50万马克的面包1 小时前
CSDN-栈队列数组-知识点整理
linux·运维·服务器
每天都要写算法(努力版)1 小时前
【行业前沿报告】DAgger:让智能体在自己走到的状态上学习
人工智能·学习·机器学习
Elastic 中国社区官方博客2 小时前
将你自己的密钥用于现有 Elastic Cloud 部署
大数据·数据库·elasticsearch·全文检索
红海云2 小时前
Jev:给智能系统做判断的模型
大数据·数据库·人工智能
wjkjpcba2 小时前
PCBA烧录程序是什么:PCBA包工包料厂家解析烧录与测试
linux·数据库·人工智能·smt贴片加工·pcba贴片加工厂
꯭自꯭闭꯭3 小时前
达梦事物特性及MVCC
linux·运维·数据库
小马同学-3 小时前
MySQL主从复制和读写分离
数据库·mysql
谢亮_vipxieliang3 小时前
Spring 事务失效的常见场景
java·开发语言·数据库·spring boot