首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C語言連接 MySQL 數據庫完整實戰:Linux 環境配置、編譯鏈接、CRUD 操作與資源管理

     編輯:關於C

環境準備(Linux)

1. 安裝開發庫


# CentOS/RHEL
yum install mysql-devel

# Ubuntu/Debian
apt-get install libmysqlclient-dev

# 驗證頭文件與庫文件
find / -name mysql.h      # 通常 /usr/include/mysql/mysql.h
find / -name libmysqlclient* # 通常 /usr/lib/mysql/ 或 /usr/lib64/mysql/

2. 編譯鏈接命令


gcc -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient main.c -o main
# -I: 頭文件路徑
# -L: 庫文件路徑
# -l: 鏈接庫 (去掉 lib 前綴和 .so/.a 後綴)

3. 運行時動態庫路徑


# 臨時
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/mysql

# 永久 (~/.bashrc)
echo 'export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib/mysql' >> ~/.bashrc

# 或編譯時嵌入 rpath(推薦)
gcc -Wl,-rpath,/usr/lib/mysql -I/usr/include/mysql -L/usr/lib/mysql -lmysqlclient main.c -o main

完整 CRUD 示例程序


#include 
#include 
#include 

#define CHECK_MYSQL(conn, stmt) \
    do { if (stmt) { \
        fprintf(stderr, "%s: %s\n", #stmt, mysql_error(conn)); \
        mysql_close(conn); exit(1); } } while(0)

int main() {
    MYSQL *conn = mysql_init(NULL);
    CHECK_MYSQL(conn, conn == NULL);

    // 連接數據庫
    if (!mysql_real_connect(conn, "localhost", "root", "password", 
                            "mylibrary", 0, NULL, 0)) {
        CHECK_MYSQL(conn, 1); // 觸發錯誤處理
    }

    // 設置字符集
    CHECK_MYSQL(conn, mysql_query(conn, "SET NAMES 'utf8'"));

    // 執行查詢:統計各出版社圖書數量
    const char *sql = 
        "SELECT COUNT(titleID), publName "
        "FROM publishers, titles "
        "WHERE publishers.publID = titles.publID "
        "GROUP BY publishers.publID "
        "ORDER BY publName";

    CHECK_MYSQL(conn, mysql_query(conn, sql));

    // 獲取結果集
    MYSQL_RES *result = mysql_store_result(conn);
    CHECK_MYSQL(conn, result == NULL);

    printf("找到 %llu 條記錄\n", (unsigned long long)mysql_num_rows(result));

    // 遍歷行
    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result))) {
        for (int i = 0; i < mysql_num_fields(result); i++) {
            printf("%s\t", row[i] ? row[i] : "[NULL]");
        }
        printf("\n");
    }

    // 釋放資源(逆序)
    mysql_free_result(result);
    mysql_close(conn);
    return 0;
}

關鍵 API 流程圖

mysql_init() → mysql_real_connect() → mysql_query() 
    → mysql_store_result() / mysql_use_result()
    → mysql_fetch_row() 循環
    → mysql_free_result()
    → mysql_close()

核心函數詳解

函數作用注意事項
mysql_init初始化 MYSQL 結構體傳 NULL 自動分配,需配對 mysql_close
mysql_real_connect建立連接參數:host, user, passwd, db, port, unix_socket, client_flag
mysql_query執行 SQL返回 0 成功,非 0 失敗;需配合 mysql_error 獲取詳情
mysql_store_result將完整結果集讀取到客戶端適用小/中結果集;大結果集用 mysql_use_result 流式讀取
mysql_fetch_row獲取下一行返回 MYSQL_ROW (char**),NULL 表示結束
mysql_num_fields列數配合 row[i] 遍歷列
mysql_free_result釋放結果集內存必須調用,否則洩漏
mysql_close關閉連接並釋放結構體程序結束前必須調用

錯誤處理最佳實踐


// 宏封裝統一錯誤處理
#define MYSQL_CHECK(conn, expr, cleanup) \
    do { if (expr) { \
        fprintf(stderr, "MySQL Error [%s:%d]: %s\n", __FILE__, __LINE__, mysql_error(conn)); \
        cleanup; \
        return -1; } } while(0)

// 使用示例
MYSQL_CHECK(conn, mysql_query(conn, sql), mysql_close(conn));
MYSQL_CHECK(conn, !(result = mysql_store_result(conn)), mysql_close(conn));

預處理語句——防 SQL 注入、提升性能


MYSQL_STMT *stmt = mysql_stmt_init(conn);
const char *sql = "INSERT INTO books(title, author, price) VALUES(?, ?, ?)";
MYSQL_CHECK(conn, mysql_stmt_prepare(stmt, sql, strlen(sql)), mysql_stmt_close(stmt));

MYSQL_BIND bind[3] = {0};
char title[100]; char author[50]; double price;
// 綁定參數...
mysql_stmt_bind_param(stmt, bind);

// 循環執行
for (int i = 0; i < n; i++) {
    // 設置 title, author, price
    MYSQL_CHECK(conn, mysql_stmt_execute(stmt), mysql_stmt_close(stmt));
}
mysql_stmt_close(stmt);

常見坑避坑指南

坑現象解決
字符集亂碼中文存入變亂碼連接後立即 SET NAMES 'utf8mb4';表/庫字符集統一 utf8mb4
結果集未釋放內存洩漏、後續查詢失敗每個 store_result 必配對 free_result
長連接斷開MySQL server has gone away啟用自動重連 mysql_options(conn, MYSQL_OPT_RECONNECT, &on) 或心跳檢測
大結果集 OOM店內存耗盡改用 mysql_use_result 流式讀取,逐行處理後釋放
編找不到庫undefined reference to mysql_init確認 -lmysqlclient 順序在源文件後,-L 路徑正確
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved