首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL C++ 封裝實戰:從 C API 到面向對象封裝

     編輯:MySQL 資料庫相關知識

近期專案將資料庫管理系統從 SQL Server 2000 遷移至 MySQL。原先採用 ADO 連接 SQL Server,遷移後為了快速搭建原型,決定直接基於 MySQL C API 進行面向對象封裝,實現資料庫建立、資料表建立、讀寫操作等核心功能。目前暫未引入連接池與事務處理模組,但基礎架構已穩定運行。

MySQL 核心特性概覽

  • 跨平台支援:由 C/C++ 編寫,經多種編譯器測試,支援 AIX、FreeBSD、Linux、Windows、macOS、Solaris 等主流作業系統。
  • 多語言 API:提供 C、C++、C#、Java、Python、PHP、Ruby 等多種程式語言介面。
  • 高併發架構:支援多執行緒,充分利用 CPU 資源,滿足多用戶並發存取需求。
  • 優化查詢引擎:採用優化的 SQL 查詢演算法,大幅提升查詢速度。
  • 靈活部署:可作為獨立客戶端/伺服器應用運行,也可作為程式庫嵌入其他軟體。
  • 多編碼支援:支援 GB2312、BIG5、Shift_JIS 等編碼作為資料表名與欄位名。
  • 多樣連接方式:提供 TCP/IP、ODBC、JDBC 等連接途徑。
  • 管理工具完善:內建管理、檢查、優化工具,支援千萬級記錄的大型資料庫處理。

主流 C++ 連接庫對比

1. MySQL Connector/C++

由 Sun Microsystems 開發,實現 JDBC 4.0 規範的 C++ 版本。介面設計參考 Java JDBC API,熟悉 JDBC 的開發者可無縫遷移,開發效率高。提供標準化的面向對象編程介面與資料庫驅動。

2. MySQL++

建立在 C++ 標準模板庫 (STL) 之上,將資料庫操作封裝為類似 STL 容器的操作體驗。提供原生 C++ 介面,減少重複性工作,適合偏好標準庫風格的開發者。

自製輕量級封裝實現

專案初期為追求快速原型驗證,未採用上述成熟庫,而是直接封裝 MySQL C API。以下是核心類 MySQLInterface 的設計與實現要點:

頭文件設計 (MySQLInterface.h)

#ifndef __MYSQL_INTERFACE_H__
#define __MYSQL_INTERFACE_H__

#include <winsock2.h>
#include <iostream>
#include <string>
#include <vector>
#include "mysql.h"

#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "libmysql.lib")

using namespace std;

class MySQLInterface {
public:
    MySQLInterface();
    virtual ~MySQLInterface();

    // 連接資料庫
    bool connectMySQL(char* server, char* username, char* password, char* database, int port);
    // 建立資料庫(不存在則建立並切換)
    bool createDatabase(std::string& dbname);
    // 執行建表 SQL
    bool createdbTable(const std::string& query);
    // 寫入資料(INSERT/UPDATE/DELETE)
    bool writeDataToDB(string queryStr);
    // 查詢資料,結果存入二維向量
    bool getDatafromDB(string queryStr, std::vector<std::vector<std::string> >& data);
    // 關閉連接
    void closeMySQL();
    // 獲取最後錯誤
    void errorIntoMySQL();

public:
    int errorNum;           // 錯誤代碼
    const char* errorInfo;  // 錯誤訊息

private:
    MYSQL mysqlInstance;    // MySQL 連接實例
    MYSQL_RES *result;      // 結果集指標
};

#endif

核心方法實現亮點

  • 建構函數初始化:呼叫 mysql_library_init、mysql_init,並設定字符集為 GBK(mysql_options(&mysqlInstance, MYSQL_SET_CHARSET_NAME, "gbk"))。
  • 連接管理:使用 mysql_real_connect 建立連接,失敗時自動記錄錯誤碼與訊息。
  • 資料庫/資料表建立:封裝 CREATE DATABASE IF NOT EXISTS 與 USE db 邏輯;建表直接執行傳入的 DDL 語句。
  • 資料寫入:統一呼叫 mysql_query 執行 DML,失敗記錄錯誤。
  • 資料讀取:使用 mysql_store_result 獲取完整結果集,逐行 (mysql_fetch_row) 解析欄位,處理 NULL 值轉為空字串,最終存入 vector<vector<string>> 便於上層業務處理。
  • 錯誤處理:統一透過 mysql_errno 與 mysql_error 獲取錯誤資訊,供外部檢查。
  • 資源釋放:解構函數中呼叫 mysql_close 關閉連接。

使用範例

MySQLInterface db;
if (db.connectMySQL("localhost", "root", "password", "testdb", 3306)) {
    db.createDatabase("testdb");
    db.createdbTable("CREATE TABLE IF NOT EXISTS users (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50))");
    db.writeDataToDB("INSERT INTO users (name) VALUES ('Alice')");
    
    std::vector<std::vector<std::string>> data;
    db.getDatafromDB("SELECT * FROM users", data);
    // 處理 data...
    db.closeMySQL();
}

後續擴展方向

  1. 引入連接池管理多連接,提升高併發效能。
  2. 實作事務支援(BEGIN/COMMIT/ROLLBACK)。
  3. 增加預處理語句封裝,防止 SQL 注入並提升重複執行效能。
  4. 支援非同步查詢與結果集流式讀取,降低大結果集記憶體佔用。

這套輕量封裝滿足了專案快速遷移與原型驗證的需求,代碼結構清晰,易於維護與擴展。若專案規模增長,建議平滑遷移至 MySQL Connector/C++ 或 MySQL++ 等成熟庫,獲得更完善的企業級特性。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved