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(现代面向对象接口,支持关系型和文档型数据操作,推荐使用)。

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

相关推荐
自不量力的A同学9 小时前
Redisson 4.2.0 发布,官方推荐的 Redis 客户端
数据库·redis·缓存
Exquisite.9 小时前
Mysql
数据库·mysql
小乔的编程内容分享站9 小时前
C语言笔记之函数
c语言·笔记
全栈前端老曹9 小时前
【MongoDB】深入研究副本集与高可用性——Replica Set 架构、故障转移、读写分离
前端·javascript·数据库·mongodb·架构·nosql·副本集
R1nG8639 小时前
CANN资源泄漏检测工具源码深度解读 实战设备内存泄漏排查
数据库·算法·cann
四谎真好看10 小时前
JavaWeb学习笔记(Day13)
笔记·学习·学习笔记·javaweb
阿钱真强道10 小时前
12 JetLinks MQTT直连设备事件上报实战(继电器场景)
linux·服务器·网络·数据库·网络协议
逍遥德10 小时前
Sring事务详解之02.如何使用编程式事务?
java·服务器·数据库·后端·sql·spring
承渊政道10 小时前
Linux系统学习【Linux基础开发工具】
linux·运维·笔记·学习·centos·编辑器
笨蛋不要掉眼泪10 小时前
Redis哨兵机制全解析:原理、配置与实战故障转移演示
java·数据库·redis·缓存·bootstrap