如何在c++中使用MySQL

在C++和Qt中操作MySQL,核心都是数据库连接 + SQL语句执行Qt中操作更简便,但关键在于驱动加载;C++中则需通过不同API手动管理连接与资源


⚙️ 方案对比:原生 C++ vs. Qt C++

特性 原生 C++ (C API / Connector/C++) Qt C++ (Qt SQL)
核心库/模块 <mysql.h> (C API) / <mysql_driver.h> (Connector/C++) [8†L12-L13] QtSql 模块 [1†L26]
连接对象 MYSQL* (C API) / sql::Connection* (Connector/C++) [7†L10] QSqlDatabase [9†L13]
SQL执行 mysql_query + mysql_store_result (C API) / sql::Statement* (Connector/C++) [7†L15][8†L19] QSqlQuery [9†L12]
结果处理 mysql_fetch_row / sql::ResultSet* [8†L21] QSqlQuery::next() + value() [9†L18-L19]
资源管理 需手动释放:mysql_free_resultmysql_close [7†L20-L21] QObject 父子机制,或使用智能指针管理
平台集成 需自行处理编译链接、头文件路径 [7†L6-L8] .pro文件添加QT += sql,无缝集成到Qt项目 [1†L30]

🔧 环境准备

使用C++/Qt操作MySQL前,需要确保开发环境准备就绪。

1. Qt 端:解决"QMYSQL driver not loaded"错误
  • 根本原因:Qt默认不包含QMYSQL驱动,需要手动提供。
  • 解决方法 :将MySQL客户端库libmysql.dll (Windows) 或 libmysqlclient.so (Linux) 复制 到Qt编译器的bin目录下。同时确保Qt、MySQL、编译器(MinGW/MSVC)的架构一致(如均为64位)
  • 注意 :Qt 5的SDK默认提供了驱动插件,位于plugins/sqldrivers/,但可能仍需libmysql.dll才能正常工作。
2. C++ 端(通用):安装连接库
  • 安装MySQL开发库 :这是C/C++连接MySQL的基础。
    • Windows (MSVC):通常包含在MySQL安装包中。
    • Linux (Debian/Ubuntu)sudo apt-get install libmysqlclient-dev
    • Linux (CentOS/RHEL)sudo yum install mysql-devel
  • 连接器选项
    • Connector/C++:官方C++库,支持面向对象接口,功能更完整。配置和编译稍显复杂,适合C++开发者。
    • C API (libmysqlclient):稳定通用,但接口是过程化的,相对底层。C++中也可用,但通常推荐Connector/C++。

🚀 连接与查询实践

📝 Qt C++ 示例

首先,在项目文件(.pro)中添加sql模块支持:

qmake 复制代码
QT += core sql

然后,在代码中实现数据库操作:

cpp 复制代码
#include <QCoreApplication>
#include <QtSql>
#include <QDebug>

int main(int argc, char *argv[]) {
    QCoreApplication a(argc, argv);

    // 1. 添加数据库驱动并创建连接
    QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
    db.setHostName("localhost");
    db.setPort(3306);
    db.setDatabaseName("my_database");
    db.setUserName("my_user");
    db.setPassword("my_password");

    // 2. 打开连接
    if (!db.open()) {
        qDebug() << "Connection failed:" << db.lastError().text();
        return -1;
    }
    qDebug() << "Connected!";

    // 3. 执行查询
    QSqlQuery query;
    if (!query.exec("SELECT id, name FROM users")) {
        qDebug() << "Query failed:" << query.lastError().text();
        return -1;
    }

    // 4. 处理结果
    while (query.next()) {
        int id = query.value(0).toInt();
        QString name = query.value(1).toString();
        qDebug() << "id:" << id << "name:" << name;
    }

    // 5. 关闭连接(可选,QSqlDatabase析构时会自动关闭)
    db.close();
    return 0;
}
📝 原生C++示例

根据项目需求和风格,可以选择不同的API实现。

方式一:使用C API (libmysqlclient)
cpp 复制代码
#include <mysql/mysql.h>
#include <iostream>

int main() {
    MYSQL *conn = mysql_init(nullptr); // 1. 初始化句柄
    if (!conn) {
        std::cerr << "mysql_init failed" << std::endl;
        return -1;
    }

    // 2. 连接服务器
    conn = mysql_real_connect(conn, "localhost", "my_user", "my_password", "my_database", 3306, nullptr, 0);
    if (!conn) {
        std::cerr << "Connect failed: " << mysql_error(conn) << std::endl;
        return -1;
    }
    std::cout << "Connected!" << std::endl;

    // 3. 执行查询
    if (mysql_query(conn, "SELECT id, name FROM users")) {
        std::cerr << "Query failed: " << mysql_error(conn) << std::endl;
        return -1;
    }

    // 4. 获取并处理结果
    MYSQL_RES *result = mysql_store_result(conn);
    if (!result) {
        std::cerr << "Store result failed" << std::endl;
        return -1;
    }

    MYSQL_ROW row;
    while ((row = mysql_fetch_row(result))) {
        std::cout << "id: " << (row[0] ? row[0] : "NULL") << ", name: " << (row[1] ? row[1] : "NULL") << std::endl;
    }

    // 5. 释放结果并关闭连接
    mysql_free_result(result);
    mysql_close(conn);
    return 0;
}
方式二:使用Connector/C++ (JDBC风格)

此API更符合C++开发者习惯,结构清晰,推荐用于新项目。

cpp 复制代码
#include <mysql_driver.h>
#include <mysql_connection.h>
#include <cppconn/statement.h>
#include <cppconn/resultset.h>
#include <cppconn/exception.h>
#include <iostream>
#include <memory>

int main() {
    try {
        // 1. 获取驱动实例
        sql::mysql::MySQL_Driver *driver = sql::mysql::get_mysql_driver_instance();

        // 2. 创建连接(注意URL格式)
        std::unique_ptr<sql::Connection> conn(driver->connect("tcp://127.0.0.1:3306", "my_user", "my_password"));
        conn->setSchema("my_database");
        std::cout << "Connected!" << std::endl;

        // 3. 创建Statement并执行查询
        std::unique_ptr<sql::Statement> stmt(conn->createStatement());
        std::unique_ptr<sql::ResultSet> res(stmt->executeQuery("SELECT id, name FROM users"));

        // 4. 处理结果集
        while (res->next()) {
            std::cout << "id: " << res->getInt("id") << ", name: " << res->getString("name") << std::endl;
        }
    } catch (sql::SQLException &e) {
        std::cerr << "SQL Error: " << e.what() << " (SQLState: " << e.getSQLState() << ")" << std::endl;
        return -1;
    }
    return 0;
}

编译时,记得链接libmysqlclient库:g++ your_program.cpp -o your_program -lmysqlclient


🗄️ 常用SQL语法指南

无论使用哪种方式,核心都是SQL语句本身。常用语法可以分为三类:

1. 数据定义 (DDL):创建、修改、删除数据库中的结构

sql 复制代码
CREATE DATABASE school;                       -- 创建数据库
USE school;                                   -- 切换/使用数据库
CREATE TABLE students (                       -- 创建表
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50) NOT NULL,
    age INT
);
ALTER TABLE students ADD COLUMN grade INT;    -- 修改表
DROP TABLE students;                          -- 删除表

2. 数据操作 (DML):处理(插入、更新、删除)表中的实际数据

sql 复制代码
INSERT INTO students (name, age) VALUES ('张三', 18);   -- 插入单条
INSERT INTO students (name, age) VALUES ('李四', 19), ('王五', 20); -- 插入多条
UPDATE students SET age = 19 WHERE name = '张三';       -- 更新
DELETE FROM students WHERE id = 3;                     -- 删除指定
DELETE FROM students;                                  -- 删除所有(危险,请谨慎)

3. 数据查询 (DQL):最常用的部分,用于从数据库中检索数据

sql 复制代码
SELECT * FROM students;                                   -- 查询所有列
SELECT name, age FROM students;                           -- 查询指定列
SELECT name, age FROM students WHERE age > 18;            -- 条件查询
SELECT name, age FROM students ORDER BY age DESC;         -- 排序
SELECT COUNT(*), AVG(age) FROM students WHERE age > 18;   -- 聚合函数
SELECT name FROM students WHERE name LIKE '张%';          -- 模糊匹配

查询书写顺序与执行顺序SELECT -> FROM -> WHERE -> GROUP BY -> HAVING -> ORDER BY -> LIMIT


🐞 常见问题与调试技巧

  1. 驱动未加载 :如上所述,通过复制libmysql.dll并确保架构一致解决。
  2. 连接失败:检查服务、主机、端口、用户名/密码。
  3. 查询失败:SQL语法错误,表/库不存在,或用户权限不足。
  4. SQL注入与参数化查询 :避免直接拼接字符串,务必 使用参数化查询/占位符
    • Qt : query.prepare("INSERT INTO users (name) VALUES (:name)"); query.bindValue(":name", name);
    • Connector/C++ : std::unique_ptr<sql::PreparedStatement> pstmt(conn->prepareStatement("SELECT * FROM users WHERE name = ?")); pstmt->setString(1, name);

本文档由AI生成

相关推荐
biter down1 小时前
3:GUI⾃动化简单⽰例
开发语言
小牛蛋1 小时前
vcpkg 管理 PCL + VTK + Qt 开发三维点云可视化软件
开发语言·qt
zandy10111 小时前
2026 BI平台安全治理体系构建:从权限模型到零信任架构
java·开发语言
纽扣6671 小时前
【C++通关之路】C++ 继承深度全景指南:从语法陷阱到内存底层的终极复习
开发语言·c++
wjs20241 小时前
Eclipse 快捷键
开发语言
楼田莉子1 小时前
C++17特性:强制省略拷贝优化/折叠表达式/非类型模板参数/嵌套命名空间
开发语言·c++
froginwe111 小时前
JavaScript JSON
开发语言
xifangge20252 小时前
Steam/Epic 游戏启动报错 0xc000007b / msvcp140.dll 缺失?VC++ 运行库底层修复指南
开发语言·c++·游戏
zuowei28892 小时前
编程语言对比:C/C++/Java/C#/PHP
java·c语言·c++