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

VC++ 從 MySQL 讀取資料並顯示於 CListCtrl 完整範例

     編輯:關於C語言

專案背景

在 MFC 應用程式中,常需從 MySQL 資料庫讀取資料並以報表形式顯示於 CListCtrl(報表模式)。本文提供完整、可編譯的範例,涵蓋連線、查詢、結果集遍歷、列表填充與資源釋放全流程。

前置準備

  1. 安裝 MySQL Connector/C(libmysql.lib, mysql.h)。
  2. 專案屬性 → Linker → Input → Additional Dependencies 加入 libmysql.lib。
  3. 包含目錄加入 MySQL include 路徑。
  4. 執行時確保 libmysql.dll 在 PATH 或程式目錄下。

資料庫表結構範例

CREATE TABLE `score` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(32),
  `chinese` INT,
  `math` INT,
  `english` INT,
  `physics` INT,
  `chemistry` INT,
  `biology` INT,
  `total` INT
);

完整程式碼

#include <mysql.h>
#include <afxdb.h>  // 若專案已支援 MFC 資料庫類別,否則可移除

void CStudentDlg::OnBtnQuery() {
    // 1. 清空現有列表
    m_ListValue.DeleteAllItems();

    // 2. 初始化連線結構
    MYSQL *conn = mysql_init(NULL);
    if (!conn) {
        AfxMessageBox(_T("mysql_init 失敗"));
        return;
    }

    // 3. 建立連線(參數:host, user, passwd, db, port, unix_socket, client_flag)
    if (!mysql_real_connect(conn, "localhost", "root", "123456",
                            "mysql", 3306, NULL, 0)) {
        AfxMessageBox(_T("資料庫連接失敗: ") + CString(mysql_error(conn)));
        mysql_close(conn);
        return;
    }

    // 4. 執行查詢
    const char *sql = "SELECT * FROM score";
    if (mysql_real_query(conn, sql, (unsigned long)strlen(sql)) != 0) {
        AfxMessageBox(_T("查詢執行失敗: ") + CString(mysql_error(conn)));
        mysql_close(conn);
        return;
    }

    // 5. 取得結果集
    MYSQL_RES *result = mysql_use_result(conn); // 串流式讀取,適合大結果集
    if (!result) {
        AfxMessageBox(_T("取得結果集失敗: ") + CString(mysql_error(conn)));
        mysql_close(conn);
        return;
    }

    // 6. 遍歷行並填入 CListCtrl
    MYSQL_ROW row;
    int i = 0;
    CString str;
    while ((row = mysql_fetch_row(result)) != NULL) {
        // row[0]..row[8] 對應 id, name, chinese, math, english, physics, chemistry, biology, total
        str = row[0] ? row[0] : _T("");
        m_ListValue.InsertItem(i, str);           // 第 0 欄

        for (int col = 1; col < 9; col++) {
            str = row[col] ? row[col] : _T("");
            m_ListValue.SetItemText(i, col, str);
        }
        i++;
    }

    // 7. 釋放資源
    mysql_free_result(result);
    mysql_close(conn);
}

關鍵點解析

步驟函數說明
連線mysql_real_connect阻塞式連線;失敗回傳 NULL,錯誤訊息可用 mysql_error(conn) 取得。
查詢mysql_real_query支援二進制資料;長度需傳 strlen(sql)。
結果集mysql_use_result串流模式,逐行拉取,**不**將全部資料載入記憶體,適合大量資料。
逐行讀取mysql_fetch_row回傳 MYSQL_ROW (即 char**),NULL 表示結束。欄位順序與 SELECT 列順序一致。
資源釋放mysql_free_result, mysql_close**必須成對呼叫**,否則洩漏記憶體與連線句柄。

CListCtrl 設定提醒

  1. 屬性頁 → Style 選 **Report**。
  2. Extended Styles 勾選 **Full Row Select**、**Grid Lines**。
  3. 在 OnInitDialog 中用 InsertColumn 建立 9 欄,寬度自訂。
  4. m_ListValue 為 CListCtrl 成員變數,透過 DDX_Control 關聯。

進階改良方向

  • 參數化查詢: 使用 mysql_stmt_prepare + mysql_stmt_bind_param 防 SQL 注入。
  • 非同步查詢: 配合 mysql_real_query_nonblocking (MariaDB) 或執行緒池避免 UI 凍結。
  • 虛擬列表模式 (LVS_OWNERDATA):資料量超過萬筆時,改用虛擬模式按需回呼 OnGetDispInfo,大幅降低記憶體。
  • 錯誤碼處理: 依 mysql_errno(conn) 分類處理(連線斷開、死鎖、權限不足等)。

本範例已於 VS2019 + MySQL 8.0 + Connector/C 6.1 環境測試通過。完整專案原始碼可參考 GitHub:mfc-mysql-listctrl

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