海东市网站建设,phpstudy2016快速搭建网站,广西网上办事大厅,简单官网模板MySQL C API的使用
介绍及使用
MySQL C API#xff08;也称为 MySQL Connector/C#xff09;是用于与 MySQL 数据库交互的 C 语言 API。它提供了一组函数和结构体#xff0c;允许你在 C 程序中连接到 MySQL 数据库服务器#xff0c;并执行查询、插入、更新等数据库操作。…MySQL C API的使用
介绍及使用
MySQL C API也称为 MySQL Connector/C是用于与 MySQL 数据库交互的 C 语言 API。它提供了一组函数和结构体允许你在 C 程序中连接到 MySQL 数据库服务器并执行查询、插入、更新等数据库操作。
以下是 MySQL C API 的基本使用步骤
1. 包含头文件
在你的 C 代码中包含 MySQL C API 的头文件
#include mysql/mysql.h2. 初始化和连接
在程序开始时需要初始化 MySQL C API 并建立与数据库服务器的连接。以下是一个简单的例子
// 这个函数初始化MySQL并返回一个MYSQL指针。这个指针在后续的操作中都会使用到。
MYSQL *conn;
conn mysql_init(NULL);if (conn NULL) {fprintf(stderr, mysql_init() failed\n);exit(1);
}
//连接到数据库mysql_real_connect()使用这个函数来连接到数据库。其中参数包括上一步得到的MYSQL指针以及数据库的主机名、用户名、密码、数据库名等。
if (mysql_real_connect(conn, localhost, user, password, database, 0, NULL, 0) NULL) {fprintf(stderr, mysql_real_connect() failed\n);mysql_close(conn);exit(1);
}
// 补充了解
// 最后三个参数大部分情况下为0,NULL,0即可三个参数详细介绍如下
port这是数据库服务端的端口号默认是MySQL的默认端口3306。如果提供0将使用默认端口
unix_socket这是Unix系统专用的如果mysql服务器运行在本地并使用了Unix socket这个参数就指定了该socket的路径。对于运行在网络上的服务器此参数通常为NULL
client_flag这是额外标志通常为0。对于特殊情况可以设置为一些特定的值比如CLIENT_COMPRESS(在客户端和服务器间进行压缩)CLIENT_SSL(使用ssl连接)CLIENT_LOCAL_FILES(允许LOAD DATA LOCAL操作)等等。详情请查阅MySQL的官方文档。
为了兼容更多的使用场景mysql_real_connect函数给出了很多参数适合应对各种复杂的数据库连接情况。但是在实际使用中大部分情况下使用默认参数port为0unix_socket为NULLclient_flag为0就足够了。在这个例子中使用 mysql_init 初始化 MySQL 对象然后使用 mysql_real_connect 建立与 MySQL 服务器的连接。你需要提供主机名、用户名、密码和数据库名。
3. 执行查询
一旦连接建立你可以执行 SQL 查询。以下是一个简单的查询示例
//mysql_query()使用这个函数来执行SQL查询。查询结果可以用后续的函数来获取。
if (mysql_query(conn, SELECT * FROM your_table)) {fprintf(stderr, SELECT query failed: %s\n, mysql_error(conn));mysql_close(conn);exit(1);
}
//获取查询结果mysql_store_result() 或 mysql_use_result()这两个函数可以获取查询结果。mysql_store_result()将所有的查询结果存储在客户端mysql_use_result()则允许你一个接一个地获取结果行。
MYSQL_RES *result mysql_store_result(conn); // 注意返回值是指针
if (result NULL) {fprintf(stderr, mysql_store_result() failed\n);mysql_close(conn);exit(1);
}
//遍历结果集mysql_fetch_row()这个函数可以获取结果集中的一行。你可以在循环中使用它来遍历所有的结果行。
int num_fields mysql_num_fields(result);
MYSQL_ROW row; //typedef char **MYSQL_ROW
while ((row mysql_fetch_row(result))) {for (int i 0; i num_fields; i) {printf(%s , row[i] ? row[i] : NULL);}printf(\n);
}mysql_free_result(result);// 补充了解
typedef struct MYSQL_RES {uint64_t row_count;MYSQL_FIELD *fields;struct MYSQL_DATA *data;MYSQL_ROWS *data_cursor;unsigned long *lengths; /* column lengths of current row */MYSQL *handle; /* for unbuffered reads */const struct MYSQL_METHODS *methods;MYSQL_ROW row; /* If unbuffered read */MYSQL_ROW current_row; /* buffer to current row */struct MEM_ROOT *field_alloc;unsigned int field_count, current_field;bool eof; /* Used by mysql_fetch_row *//* mysql_stmt_close() had to cancel this result */bool unbuffered_fetch_cancelled;enum enum_resultset_metadata metadata;void *extension;
} MYSQL_RES;这个例子执行一个简单的 SELECT 查询然后使用 mysql_store_result 获取查询结果并使用 mysql_fetch_row 逐行读取结果集中的数据。
4. 插入、更新和删除
你可以使用 mysql_query 函数执行插入、更新和删除等修改数据库的操作。以下是一个插入数据的示例
if (mysql_query(conn, INSERT INTO your_table (column1, column2) VALUES (value1, value2))) {fprintf(stderr, INSERT query failed: %s\n, mysql_error(conn));mysql_close(conn);exit(1);
}5. 清理结果集
//清理结果集mysql_free_result()当你处理完查询结果后需要调用这个函数来清理结果集。
mysql_free_result(result);
mysql_close(conn);6.关闭连接
在程序结束时确保关闭与 MySQL 服务器的连接并释放资源
mysql_close(conn);这些是 MySQL C API 的基本用法示例。请注意为了简洁起见没有进行错误处理的详细检查。在实际应用中应该更加详细地处理错误以确保程序的稳定性。
API封装
以下为个人在使用过程中对API的进一步封装
class DataBase {public:~DataBase() {Close(); // 析构函数自动关闭数据库}// 初始化,可以指定连接的 用户名密码数据存储库host,portvoid Init(string name, string pwd, string database, string host localhost, int port 3306) {mysql_init(mysql_);// 连接数据库if (mysql_real_connect(mysql_, host.c_str(), name.c_str(), pwd.c_str(), database.c_str(), port, NULL, 0) NULL) {cout mysql_error(mysql_) endl;cout connect error! endl;exit(-1);}// 设置字符集编码包含了character_set_connection为utf8mb4因为库以及表采用的是utf8mb4字符集if (!mysql_set_character_set(mysql_, utf8mb4)){printf(New client character set: %s\n, mysql_character_set_name(mysql_));}// 设置character_set_client 客户端字符集为GBK因为命令行窗口是GBK编码否则mysql 1366 error// 设置character_set_results 查询结果集为GBK,因为命令行窗口是GBK编码要对应起来否乱码if (!Query(set character_set_client gbk) || !Query(set character_set_results gbk)) {cout set character_set_client or character_set_results gbk error: Error() endl;}}// 执行语句bool Query(const string query) {// 成功0,失败非0return !mysql_query(mysql_, query.c_str());}// 释放结果集void FreeResult() {mysql_free_result(res_);}// 返回记录行数int Rows() {return mysql_num_rows(res_);}// 返回字段数量int Cols() {return mysql_num_fields(res_);}// 关闭数据库void Close() {mysql_close(mysql_);}// 获取查询结果集MYSQL_RES* GetResult() {return res_ mysql_store_result(mysql_);}// 获取表字段MYSQL_FIELD* GetFields() {return mysql_fetch_fields(res_);}const char* Error() {return mysql_error(mysql_);}// 获取一行记录MYSQL_ROW FetchRow() {return row_ mysql_fetch_row(res_);}// 不区分大小写进行比较字符串主要用于字段名比较bool InsensistiveStringCompare(const string str1, const string str2) {string str1Cpy(str1);string str2Cpy(str2);transform(str1Cpy.begin(), str1Cpy.end(), str1Cpy.begin(), ::tolower);transform(str2Cpy.begin(), str2Cpy.end(), str2Cpy.begin(), ::tolower);return (str1Cpy str2Cpy);}// 输出结果集便于调试void Show(const string query) {if (!Query(query)) {cout show test error: Error() endl;exit(-1);}MYSQL_RES* res GetResult();if (!res) {cout GetResult error: Error() endl;exit(-1);}int n Rows(), m Cols();cout 共 n 条记录, m 个字段 endl;MYSQL_ROW row;string field;vectorvectorstring records(n 1, vectorstring(m));vectorint max_len(m); // 记录每列数据的最大长度便于格式化输出 int len 0;MYSQL_FIELD* fields GetFields();for (int i 0; i m; i) {records[0][i] fields[i].name; // 获取字段名max_len[i] (int)max(fields[i].name_length, fields[i].max_length); // 获取字段记录最大长度以及字段长度记录最大值}for (int i 1; i n; i) {row FetchRow();for (int j 0; j m; j) {if (row[j]) field row[j];else field NULL;records[i][j] field;len max(len, sizeof field);}}for (int i 0; i n; i) {for (int j 0; j m; j) {cout setiosflags(ios::left) setw(max_len[j] 2) records[i][j] ;}cout endl;}}
private:MYSQL mysql_; // 数据库句柄MYSQL_RES* res_; // 查询结果集合MYSQL_ROW row_; // 记录结构体};