C語言連接MySQL數(shù)據(jù)庫的完整流程
大家好,最近在學(xué)習(xí)數(shù)據(jù)庫編程,今天把C 語言連接 MySQL的完整流程整理成一篇超詳細(xì)博客,從庫文件配置、編譯運(yùn)行,到 API 函數(shù)詳解、完整代碼實戰(zhàn),一步一步帶你上手,新手也能直接跟著做!
一、前言:為什么用 C 語言連接 MySQL?
MySQL 官方提供了 C 語言原生 API(Connector/C),這是所有語言(Python/Java/PHP)連接 MySQL 的底層基礎(chǔ),性能最高、可控性最強(qiáng),非常適合:
- 后端服務(wù)、嵌入式設(shè)備數(shù)據(jù)庫操作
- 學(xué)習(xí)數(shù)據(jù)庫底層交互原理
- 高性能數(shù)據(jù)存取場景
本文完全基于官方庫,不依賴第三方封裝,可直接編譯運(yùn)行。
二、環(huán)境準(zhǔn)備:Connector/C 庫下載與結(jié)構(gòu)
1. 下載官方庫
前往 MySQL 官網(wǎng)下載 Connector/C
選擇對應(yīng)系統(tǒng)版本(Linux 64 位 / Windows),下載后解壓得到兩個核心目錄:
mysql-connector-c/
├── include/ # 頭文件:所有函數(shù)聲明(mysql.h 等)
└── lib/ # 庫文件:函數(shù)實現(xiàn)(.so / .a)
2. 庫文件作用(必看)
include:告訴編譯器有哪些函數(shù)可以調(diào)用lib:告訴鏈接器函數(shù)的實現(xiàn)在哪里- 核心庫:
libmysqlclient(動態(tài)庫.so/ 靜態(tài)庫.a)
三、第一步:驗證庫引入成功(最簡測試)
在寫復(fù)雜連接前,先做最小驗證,確保環(huán)境配置正確。
1. 測試代碼(test.c)
#include <stdio.h>
#include <mysql.h> // 必須包含 MySQL 核心頭文件
int main() {
// 獲取客戶端庫版本
const char* version = mysql_get_client_info();
printf("MySQL Client Version: %s\n", version);
return 0;
}
2. 編譯命令(關(guān)鍵)
gcc -o test test.c -I./include -L./lib -lmysqlclient
參數(shù)說明:
-I./include:指定頭文件路徑-L./lib:指定庫文件路徑-lmysqlclient:鏈接libmysqlclient庫
3. 運(yùn)行與動態(tài)庫問題解決
直接運(yùn)行可能報錯:
error while loading shared libraries: libmysqlclient.so.18
原因:系統(tǒng)找不到動態(tài)庫,臨時設(shè)置環(huán)境變量:
export LD_LIBRARY_PATH=./lib ./test
成功輸出:
MySQL Client Version: 6.1.6
庫引入成功!
四、MySQL C API 核心函數(shù)全解
C 語言操作 MySQL 固定5 步流程:
初始化 → 2. 連接數(shù)據(jù)庫 → 3. 執(zhí)行 SQL → 4. 獲取結(jié)果 → 5. 關(guān)閉連接
1. 初始化:mysql_init
MYSQL* mysql_init(MYSQL* mysql);
- 作用:初始化 MySQL 操作句柄(必須第一步)
- 傳 NULL:自動分配空間
- 返回值:成功返回 MYSQL* 句柄,失敗 NULL
示例:
MYSQL* mysql = mysql_init(NULL);
if (mysql == NULL) {
printf("初始化失敗\n");
return 1;
}
2. 建立連接:mysql_real_connect
MYSQL* mysql_real_connect(
MYSQL* mysql,
const char* host, // 主機(jī):localhost / 127.0.0.1
const char* user, // 用戶名:root
const char* passwd, // 密碼
const char* db, // 要連接的數(shù)據(jù)庫名
unsigned int port, // 端口:3306
const char* unix_socket,// NULL
unsigned long clientflag// 0
);
連接成功后必須設(shè)置字符集,否則中文亂碼:
mysql_set_character_set(mysql, "utf8");
3. 執(zhí)行 SQL:mysql_query
int mysql_query(MYSQL* mysql, const char* sql);
- 作用:下發(fā) SQL 語句(增刪改查都用它)
- 返回 0 成功,非 0 失敗
4. 獲取查詢結(jié)果(SELECT 專用)
mysql_store_result(MYSQL*):把結(jié)果讀到內(nèi)存mysql_num_rows(MYSQL_RES*):獲取結(jié)果行數(shù)mysql_num_fields(MYSQL_RES*):獲取列數(shù)mysql_fetch_fields(MYSQL_RES*):獲取列名mysql_fetch_row(MYSQL_RES*):逐行獲取數(shù)據(jù)
特別注意:MYSQL_RES* 是 malloc 申請的空間,必須手動釋放,否則內(nèi)存泄漏!
MYSQL_RES* result = mysql_store_result(mysql); // ... 使用結(jié)果 mysql_free_result(result);
5. 關(guān)閉連接:mysql_close
mysql_close(mysql);
五、完整實戰(zhàn)代碼:連接 + 查詢 + 打印
直接復(fù)制可用,替換自己的數(shù)據(jù)庫信息即可運(yùn)行!
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <mysql.h>
int main() {
// 1. 初始化
MYSQL* mysql = mysql_init(NULL);
if (mysql == NULL) {
printf("mysql_init 失敗\n");
return 1;
}
// 2. 連接數(shù)據(jù)庫(請修改為你的信息)
const char* host = "localhost";
const char* user = "root";
const char* passwd = "123456";
const char* db = "test";
unsigned int port = 3306;
if (mysql_real_connect(mysql, host, user, passwd, db, port, NULL, 0) == NULL) {
printf("連接失敗: %s\n", mysql_error(mysql));
mysql_close(mysql);
return 1;
}
printf("數(shù)據(jù)庫連接成功 ?\n");
mysql_set_character_set(mysql, "utf8");
// 3. 執(zhí)行查詢 SQL
const char* sql = "SELECT id, name, age FROM student;";
if (mysql_query(mysql, sql) != 0) {
printf("查詢失敗: %s\n", mysql_error(mysql));
mysql_close(mysql);
return 1;
}
// 4. 獲取結(jié)果
MYSQL_RES* res = mysql_store_result(mysql);
if (res == NULL) {
printf("無結(jié)果或執(zhí)行失敗\n");
mysql_close(mysql);
return 1;
}
// 列數(shù)、列名
int fields = mysql_num_fields(res);
MYSQL_FIELD* field = mysql_fetch_fields(res);
for (int i = 0; i < fields; i++) {
printf("%s\t", field[i].name);
}
printf("\n----------------------------------------\n");
// 逐行打印
MYSQL_ROW row;
while ((row = mysql_fetch_row(res)) != NULL) {
for (int i = 0; i < fields; i++) {
printf("%s\t", row[i] ? row[i] : "NULL");
}
printf("\n");
}
// 5. 釋放資源 + 關(guān)閉
mysql_free_result(res);
mysql_close(mysql);
printf("\n操作完成 ?\n");
return 0;
}
六、編譯運(yùn)行命令
gcc -o mysql_demo mysql_demo.c -I./include -L./lib -lmysqlclient export LD_LIBRARY_PATH=./lib ./mysql_demo
七、常見問題匯總(避坑指南)
1.中文亂碼
連接成功后必須加:
mysql_set_character_set(mysql, "utf8");
2.動態(tài)庫找不到
export LD_LIBRARY_PATH=./lib
3.連接失敗 Access denied
檢查 host、user、password、port、db 是否正確
4.內(nèi)存泄漏
MYSQL_RES* 必須 mysql_free_result
八、擴(kuò)展:事務(wù)支持(非常重要)
MySQL C API 原生支持事務(wù):
mysql_autocommit(mysql, 0); // 關(guān)閉自動提交 // 執(zhí)行多條 SQL... mysql_commit(mysql); // 提交 // 出錯則回滾 mysql_rollback(mysql);
九、總結(jié)
C 語言連接 MySQL 其實非常簡單,記住固定流程:初始化 → 連接 → 執(zhí)行 SQL → 獲取結(jié)果 → 釋放關(guān)閉。
到此這篇關(guān)于C語言連接MySQL數(shù)據(jù)庫的完整流程的文章就介紹到這了,更多相關(guān)C語言連接MySQL數(shù)據(jù)庫內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++深入探究哈希表如何封裝出unordered_set和unordered_map
哈希表是一種根據(jù)關(guān)鍵碼去尋找值的數(shù)據(jù)映射結(jié)構(gòu),該結(jié)構(gòu)通過把關(guān)鍵碼映射的位置去尋找存放值的地方,說起來可能感覺有點復(fù)雜,我想我舉個例子你就會明白了,最典型的的例子就是字典2022-06-06
C語言不用鏈表完成學(xué)生管理系統(tǒng)(完整代碼)
這篇文章主要介紹了C語言不用鏈表完成學(xué)生管理系統(tǒng)(完整代碼),本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04
C++?數(shù)據(jù)結(jié)構(gòu)超詳細(xì)講解單鏈表
這篇文章主要介紹了C++數(shù)據(jù)結(jié)構(gòu)之單鏈表,鏈表是由一個個結(jié)點鏈結(jié)成的。結(jié)點包括數(shù)據(jù)域和指針域兩部分,數(shù)據(jù)域用來存儲數(shù)據(jù)元素的信息,指針域用來存儲下一個結(jié)點的地址,更詳細(xì)內(nèi)容請需要的小伙伴參考下面文章內(nèi)容2022-03-03

