如何在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†L158†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生成

相关推荐
王小王-12311 小时前
基于深度学习的个性化音乐推荐系统的设计与开发
人工智能·深度学习·mysql·vue·推荐算法·个性化音乐推荐系统·音乐预测
兰令水11 小时前
leecodecode【单调栈】【2026.6.12打卡-java版本】
java·开发语言·算法
leagsoft_100312 小时前
零信任选型五刀法——零信任怎么选?五个问题,五条红线
开发语言·php
AI人工智能+电脑小能手12 小时前
【大白话说Java面试题 第112题】【并发篇】第12题:AQS 中节点的入队时机有哪些?
java·开发语言·面试
IT WorryFree12 小时前
Zabbix 7.4 API 可同步全量参数清单(同步第三方系统专用)
java·开发语言·zabbix
码云骑士12 小时前
06-Python装饰器从入门到源码(上)-闭包与自由变量
开发语言·python
码云骑士12 小时前
10-Python运行时内存模型-栈帧-堆-引用计数-GC分代回收的全景图
开发语言·python
xuefuhe12 小时前
MySQL8.4 tar.xz安装
mysql
智码看视界12 小时前
老梁聊全栈系列 JavaScript语言本质:从原型链到异步编程的深度解析
开发语言·javascript·全栈·javascript核心
AI科技星12 小时前
数术工坊・八卷全书【本源创世终极版・万世定稿】
开发语言·网络·量子计算·拓扑学