在 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(现代面向对象接口,支持关系型和文档型数据操作,推荐使用)。
详细的介绍留待将来补充。。。