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

C語言連接MySQL數據庫完整實戰:Linux環境下增刪改查

     編輯:關於C語言

開發環境準備

  • OS:RedHat 6.3 32位(現代建議使用 Ubuntu 20.04+ 64位)
  • MySQL:5.6.15+(當前主流 8.0+)
  • 編譯器:GCC 4.4.6+(現代 9.0+)
  • 開發庫:sudo apt-get install libmysqlclient-dev (Debian/Ubuntu)

編譯鏈接命令詳解

gcc -I/usr/include/mysql -L/usr/lib -lmysqlclient main.c -o main.out
  • -I:指定頭文件目錄(mysql.h 位置)
  • -L:指定動態庫目錄(libmysqlclient.so 位置)
  • -lmysqlclient:鏈接 MySQL 客戶端庫
  • -o:輸出可執行文件名

64位系統庫路徑通常為 /usr/lib/x86_64-linux-gnu,可用 mysql_config --cflags --libs 自動獲取參數。

核心API流程

  1. mysql_init():初始化 MYSQL 句柄
  2. mysql_real_connect():建立連接(主機、用戶、密碼、數據庫、端口、Unix socket、客戶端標誌)
  3. mysql_set_character_set():設置字符集(推薦 utf8mb4)
  4. 執行 SQL:mysql_real_query() 或預處理 mysql_stmt_* 系列
  5. 結果集處理:mysql_store_result()(全部讀入內存)或 mysql_use_result()(流式讀取)
  6. 資源釋放:mysql_free_result(), mysql_stmt_close(), mysql_close()

關鍵功能代碼片段

參數化插入(預處理)防注入

MYSQL_STMT *stmt = mysql_stmt_init(&mysql);
const char *sql = "INSERT INTO t_user(name,age,address) VALUES (?,?,?)";
mysql_stmt_prepare(stmt, sql, strlen(sql));

MYSQL_BIND bind[3] = {0};
char name[] = "hanzhiqiang"; int age = 30; char addr[] = "heimuer";

bind[0].buffer = name; bind[0].buffer_type = MYSQL_TYPE_STRING; bind[0].buffer_length = strlen(name);
bind[1].buffer = &age; bind[1].buffer_type = MYSQL_TYPE_LONG; bind[1].buffer_length = sizeof(int);
bind[2].buffer = addr; bind[2].buffer_type = MYSQL_TYPE_STRING; bind[2].buffer_length = strlen(addr);

mysql_stmt_bind_param(stmt, bind);
mysql_stmt_execute(stmt);
printf("插入ID: %lld, 影響行數: %lld\n", mysql_stmt_insert_id(stmt), mysql_stmt_affected_rows(stmt));
mysql_stmt_close(stmt);

查詢結果遍歷

mysql_real_query(&mysql, "SELECT * FROM t_user", strlen(sql));
MYSQL_RES *res = mysql_store_result(&mysql);
MYSQL_FIELD *fields = mysql_fetch_fields(res);
for (int i = 0; i < mysql_num_fields(res); i++) printf("%s\t", fields[i].name);
printf("\n");
MYSQL_ROW row;
while ((row = mysql_fetch_row(res))) {
    for (int i = 0; i < mysql_num_fields(res); i++) printf("%s\t", row[i] ? row[i] : "NULL");
    printf("\n");
}
mysql_free_result(res);

事務控制

mysql_autocommit(&mysql, 0); // 關閉自動提交
// ... 多條 SQL ...
mysql_commit(&mysql);        // 提交
// 或出錯時
mysql_rollback(&mysql);      // 回滾

常見問題與最佳實踐

問題解決方案
中文亂碼連接後執行 SET NAMES utf8mb4,表字符集設為 utf8mb4
連接超時設置 MYSQL_OPT_RECONNECT 或心跳機制
SQL注入強制使用預處理語句,絕不拼接用戶輸入
內存洩漏嚴格配對 mysql_free_result/mysql_stmt_close/mysql_close
大結果集使用 mysql_use_result 流式讀取,避免 store_result 佔用大量內存

現代化建議

  • 使用連接池(如 libmysqlclient 內置或第三方 mysql++, ODBC)
  • 考慮 ORM 框架簡化 CRUD 代碼
  • 生產環境啟用 SSL 連接:mysql_ssl_set()
  • 錯誤處理統一封裝為日誌記錄與重試邏輯
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved