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 的基本步骤:

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

1.1 安装

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

sudo apt-get update
sudo apt-get install libmysqlclient-dev

头文件路径:

/usr/include/mysql/mysql.h

#include <mysql/mysql.h>

1.2 常用接口与使用方法

1.2.1 初始化连接句柄
MYSQL* mysql_init(MYSQL* mysql);
  • 功能:初始化一个 MYSQL 结构体(连接句柄),用于后续数据库操作。
  • 参数
    • mysql:若为 NULL,函数会自动分配一个新的 MYSQL 结构体;若传入已存在的句柄,会重置其状态。
  • 返回值
    • 成功:返回初始化后的 MYSQL* 句柄;
    • 失败:返回 NULL(内存不足)。
1.2.2 连接数据库
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

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

(2)mysql_real_query

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**类型。
    typedef char **MYSQL_ROW;                /* return data as array of strings */
  • MYSQL_FIELD:查询结果中一列(属性),本质是包含某列各种属性的结构体。
    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
    • 原型
      MYSQL_RES* mysql_store_result(MYSQL* mysql);
    • 功能:一次性将所有查询结果读取到客户端内存,适合小结果集(后续可随机访问)。
    • 返回值:成功返回结果集 MYSQL_RES*,失败返回 NULL。
  • mysql_use_result
    • 原型
      MYSQL_RES* mysql_use_result(MYSQL* mysql);
    • 功能:逐行从服务器获取结果(不缓存到客户端),适合大结果集(内存占用低,但必须读完所有行才能执行新查询)。
    • 返回值:成功返回单行数据结果集,失败返回 NULL。

(2)获取行数与列数

  • mysql_num_rows
    • 原型
      my_ulonglong mysql_num_rows(MYSQL_RES* result);
    • 功能:获取结果集中的行数(仅对 mysql_store_result 有效)。
  • mysql_num_fields
    • 原型
      unsigned int mysql_num_fields(MYSQL_RES* result);
    • 功能:获取结果集中的列数。

(3)获取行数据

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

(4)获取字段信息

MYSQL_FIELD* mysql_fetch_field(MYSQL_RES* result);
  • 功能:获取列的元信息(如字段名、类型)。
  • 返回值:返回下一个字段的 MYSQL_FIELD 结构体(包含 name、type 等成员),无更多字段时返回 NULL。
1.2.5 错误处理
  • mysql_error
    • 原型
      const char* mysql_error(MYSQL* mysql);
    • 功能:返回最后一次操作的错误信息(字符串)。
  • mysql_errno
    • 原型
      unsigned int mysql_errno(MYSQL* mysql);
    • 功能:返回最后一次操作的错误码(整数,可参考 MySQL 错误码表)。
1.2.6 关闭连接与释放资源
  • mysql_close
    • 原型
      void mysql_close(MYSQL* mysql);
    • 功能:关闭数据库连接并释放 MYSQL 句柄。
  • mysql_free_result
    • 原型
      void mysql_free_result(MYSQL_RES* result);
    • 功能:释放结果集(必须在处理完结果后调用)。

1.3 使用示例

#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):

g++ -o test test.cpp -std=c++11 -lmysqlclient

2. MySQL Connector/C++

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大筒木老辈子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值