MySQL笔记---C/C++访问MySQL数据库

在 C++ 中访问 MySQL 数据库,最常用的方式是通过官方提供的MySQL Connector/C++ (C++ 驱动)或基于 C API的封装。

  • MySQL Connector/C++:面向对象封装的库,更加适配C++,也更方便。
  • MySQL C API:是面向过程封装的库,主要用于需要兼容C语言的场景,使用起来比较麻烦。

1. MySQL C API

MySQL C API 是 MySQL 提供的一套基于 C 语言的底层接口,用于与 MySQL 数据库进行交互。它是许多高层语言(如 Python、PHP)数据库驱动的底层实现,功能全面但需要手动管理资源。

使用 MySQL C API 的基本步骤:

bash 复制代码
初始化连接句柄 → 连接数据库 → 执行 SQL 语句 → 处理结果集 → 释放资源 → 关闭连接

1.1 安装

安装 MySQL C 客户端开发库(mysqlclient):

bash 复制代码
sudo apt-get update
sudo apt-get install libmysqlclient-dev

头文件路径:

bash 复制代码
/usr/include/mysql/mysql.h

#include <mysql/mysql.h>

1.2 常用接口与使用方法

1.2.1 初始化连接句柄
cpp 复制代码
MYSQL* mysql_init(MYSQL* mysql);
  • 功能 :初始化一个 MYSQL 结构体(连接句柄),用于后续数据库操作。
  • 参数
    • mysql:若为 NULL,函数会自动分配一个新的 MYSQL 结构体;若传入已存在的句柄,会重置其状态。
  • 返回值
    • 成功:返回初始化后的 MYSQL* 句柄;
    • 失败:返回 NULL(内存不足)。
1.2.2 连接数据库
cpp 复制代码
MYSQL* mysql_real_connect(
    MYSQL* mysql,          // 已初始化的句柄
    const char* host,      // 主机名("localhost"或IP,本地可填NULL)
    const char* user,      // 用户名(如"root")
    const char* passwd,    // 密码
    const char* db,        // 要连接的数据库名(NULL表示不指定)
    unsigned int port,     // 端口号(默认3306,填0表示默认)
    const char* unix_socket,// Unix域套接字(NULL表示不使用)
    unsigned long client_flag  // 客户端标志(0表示默认)
);
  • 功能:通过初始化的句柄连接到 MySQL 服务器。
  • 返回值
    • 成功:返回 mysql 句柄(与传入的一致);
    • 失败:返回 NULL。
1.2.3 执行 SQL 语句

(1)mysql_query

cpp 复制代码
int mysql_query(MYSQL* mysql, const char* stmt_str);
  • 功能:执行字符串形式的 SQL 语句(适合普通文本 SQL)。
  • 参数
    • stmt_str:以 \0 结尾的 SQL 字符串(如 "SELECT * FROM user")。
  • 返回值
    • 成功:0;
    • 失败:非 0。

(2)mysql_real_query

cpp 复制代码
int mysql_real_query(MYSQL* mysql, const char* stmt_str, unsigned long length);
  • 功能:执行 SQL 语句(适合包含二进制数据或 \0 字符的 SQL,需指定长度)。
  • 参数:
    • length:SQL 字符串的长度(字节数)。
  • 返回值:与 mysql_query 一致。
1.2.4 处理结果集

执行查询语句(如 SELECT)后,需通过以下函数获取并解析结果。

  • MYSQL_RES:查询语句的结果,结果中的所有数据都以字符串的形式保存,可抽象地认为这是一个存放字符串的二维数组(表格)。

  • MYSQL_ROW :查询结果中的一行(数据),本质是char**类型。

    cpp 复制代码
    typedef char **MYSQL_ROW;                /* return data as array of strings */
  • MYSQL_FIELD :查询结果中一列(属性),本质是包含某列各种属性的结构体。

    cpp 复制代码
    typedef struct MYSQL_FIELD {
      char *name;               /* Name of column */
      char *org_name;           /* Original column name, if an alias */
      char *table;              /* Table of column if column was a field */
      char *org_table;          /* Org table name, if table was an alias */
      char *db;                 /* Database for table */
      char *catalog;            /* Catalog for table */
      char *def;                /* Default value (set by mysql_list_fields) */
      unsigned long length;     /* Width of column (create length) */
      unsigned long max_length; /* Max width for selected set */
      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;         /* Div flags */
      unsigned int decimals;      /* Number of decimals in field */
      unsigned int charsetnr;     /* Character set */
      enum enum_field_types type; /* Type of field. See mysql_com.h for types */
      void *extension;
    } MYSQL_FIELD;

(1)获取结果集

  • mysql_store_result
    • 原型

      cpp 复制代码
      MYSQL_RES* mysql_store_result(MYSQL* mysql);
    • 功能:一次性将所有查询结果读取到客户端内存,适合小结果集(后续可随机访问)。

    • 返回值:成功返回结果集 MYSQL_RES*,失败返回 NULL。

  • mysql_use_result
    • 原型

      cpp 复制代码
      MYSQL_RES* mysql_use_result(MYSQL* mysql);
    • 功能:逐行从服务器获取结果(不缓存到客户端),适合大结果集(内存占用低,但必须读完所有行才能执行新查询)。

    • 返回值:成功返回单行数据结果集,失败返回 NULL。

(2)获取行数与列数

  • mysql_num_rows
    • 原型

      cpp 复制代码
      my_ulonglong mysql_num_rows(MYSQL_RES* result);
    • 功能:获取结果集中的行数(仅对 mysql_store_result 有效)。

  • mysql_num_fields
    • 原型

      cpp 复制代码
      unsigned int mysql_num_fields(MYSQL_RES* result);
    • 功能:获取结果集中的列数。

(3)获取行数据

cpp 复制代码
MYSQL_ROW mysql_fetch_row(MYSQL_RES* result);
  • 功能:从结果集中获取一行数据(以字符串数组形式返回)。
  • 返回值
    • 成功:返回 MYSQL_ROW(本质是 char**,每个元素对应一列的值,NULL 表示该列值为 NULL);
    • 无更多行或失败:返回 NULL。

(4)获取字段信息

cpp 复制代码
MYSQL_FIELD* mysql_fetch_field(MYSQL_RES* result);
  • 功能:获取列的元信息(如字段名、类型)。
  • 返回值:返回下一个字段的 MYSQL_FIELD 结构体(包含 name、type 等成员),无更多字段时返回 NULL。
1.2.5 错误处理
  • mysql_error
    • 原型

      cpp 复制代码
      const char* mysql_error(MYSQL* mysql);
    • 功能:返回最后一次操作的错误信息(字符串)。

  • mysql_errno
    • 原型

      cpp 复制代码
      unsigned int mysql_errno(MYSQL* mysql);
    • 功能:返回最后一次操作的错误码(整数,可参考 MySQL 错误码表)。

1.2.6 关闭连接与释放资源
  • mysql_close
    • 原型

      cpp 复制代码
      void mysql_close(MYSQL* mysql);
    • 功能:关闭数据库连接并释放 MYSQL 句柄。

  • mysql_free_result
    • 原型

      cpp 复制代码
      void mysql_free_result(MYSQL_RES* result);
    • 功能:释放结果集(必须在处理完结果后调用)。

1.3 使用示例

cpp 复制代码
#include <iostream>
#include <mysql/mysql.h>
#include <string>

std::string host = "localhost";
std::string user = "****";
std::string password = "****";
std::string database = "test_connector";
unsigned int port = 3306;

int main()
{
    // 初始化连接
    MYSQL *conn = mysql_init(nullptr);
    if(!mysql_real_connect(conn, host.c_str(), user.c_str(), password.c_str(), database.c_str(), port, nullptr, 0))
    {
        std::cerr << "建立连接失败! " << mysql_error(conn) << std::endl;
        return 1;
    }

    // 查询
    std::string sql = "SELECT * FROM user";
    if(mysql_query(conn, sql.c_str()))
    {
        std::cerr << "查询失败! " << mysql_error(conn) << std::endl;
        return 1;
    }

    // 处理结果
    MYSQL_RES *res = mysql_store_result(conn);
    my_ulonglong row_num = mysql_num_rows(res);
    my_ulonglong col_num = mysql_num_fields(res);

    MYSQL_FIELD *fild;
    while(fild = mysql_fetch_field(res))
    {
        std::cout << fild->name << '\t';
    }
    std::cout << std::endl;

    MYSQL_ROW row;
    while(row = mysql_fetch_row(res))
    {
        for(int i = 0; i < row_num; i++)
        {
            std::cout << row[i] << "\t";
        }
        std::cout << std::endl;
    }

    // 释放资源
    mysql_free_result(res);
    mysql_close(conn);

    return 0;
}

编译时需链接 MySQL C 客户端库(-lmysqlclient):

bash 复制代码
g++ -o test test.cpp -std=c++11 -lmysqlclient

2. MySQL Connector/C++

MySQL Connector/C++ 是 MySQL 官方提供的 C++ 驱动库,用于在 C++ 程序中与 MySQL 数据库交互。

它提供了两套主要接口:传统 API (基于 JDBC 风格的封装,兼容旧版本) 和 X DevAPI(现代面向对象接口,支持关系型和文档型数据操作,推荐使用)。

详细的介绍留待将来补充。。。

相关推荐
foolishlee几秒前
Neon wal日志处理流程
数据库
星马梦缘8 分钟前
数据库 事务管理 专项作战记录
数据库
名字还没想好☜23 分钟前
Python concurrent.futures 实战:用 ThreadPoolExecutor 并发处理 + as_completed 收结果
数据库·python·php·并发
空杆推不起36 分钟前
穿透数据库 JOIN 核心:语法分类、底层算法、生产优化与高频坑点全解析
数据库·oracle
xxwl5851 小时前
数据库后端接口测试报告
spring boot·mysql·tomcat
xqqxqxxq1 小时前
MySQL 数据类型笔记
数据库·笔记·mysql
Logintern092 小时前
理解MySQL数据库的“事务与锁”
数据库·mysql
朱容zr3331332 小时前
为什么推荐使用自增主键?使用UUID作为主键的优缺点是什么?
java·运维·数据库·后端·mysql·面试·性能优化
麻瓜code2 小时前
【Redis 】数据类型、持久化与过期删除
数据库·redis·缓存
空杆推不起2 小时前
穿透 Flink CDC 表层用法:数据库日志捕获机制、Flink Source 运行时、端到端一致性底层原理详解
大数据·数据库·flink