Skip to content

数据库操作

QSQDatabase 是 Qt SQL模块中的核心类,用于管理数据库连接。它提供了统一的 API,屏蔽了底层数据库的差异。

核心功能

  • 创建、配置和管理数据库连接。
  • 执行 SQL 语句(查询、插入、更新、删除等)。
  • 事务管理(提交、回滚)。
  • 错误处理与状态查询。

支持的数据库驱动

  • SQLite(轻量级,无需服务器,默认支持)。
  • MySQL、PostgreSQL(需安装对应驱动和客户端库)。
  • ODBC(兼容 Windows 数据库接口)。

QSqlDatabase类

QSqlDatabase 类是 Qt 数据库模块中用于管理数据库连接的关键类之一。它提供了连接到各种数据库系统的能力,比如 SQLite、MySQL、PostgreSQL 等。主要功能包括创建连接、打开和关闭连接、设置连接参数以及管理连接池。

1. 添加数据库连接

  • 可以使用 addDatabase 函数来添加一个数据库连接。该函数有两种常见的用法:
    • addDatabase(const QString &type, const QString &connectionName = QuatiniString(defaultConnection));
      • 添加一个数据库连接,其中 type 参数指定数据库类型(例如 “QSQLITE”、“QMYSQL” 等),connectionName 参数指定连接的名称,默认为 “defaultConnection”。
    • addDatabase(QSqlDriver *driver, const QString &connectionName = QuatiniString(defaultConnection));
      • 添加一个数据库连接,使用给定的驱动程序 driver 对象。这种用法通常用于自定义的数据库驱动程序。

2. 设置连接参数

  • 一旦添加了数据库连接,可以使用一系列函数来设置连接的参数:
    • setDatabaseName(const QString &name): 设置数据库的名称(对于 SQLite 数据库是文件路径,对于其他数据库是数据库名)。
    • setHostName(const QString &host): 设置数据库服务器的主机名。
    • setUserName(const QString &name): 设置数据库用户名。
    • setPassword(const QString &password): 设置数据库密码。

3. 打开和关闭连接

  • 一旦设置了连接参数,可以使用 open() 函数打开数据库连接,并使用 close() 函数关闭数据库连接。可以使用 isOpen() 函数检查连接是否已打开。

4. 连接状态和有效性

  • 可以使用 isValid() 函数检查数据库连接是否有效。一个有效的连接是指已经成功添加到连接池中的连接,并且未被移除。

5. 连接池管理

  • Qt 的数据库模块还提供了连接池的功能,可以通过 removeDatabase() 函数从连接池中移除指定的数据库连接。这在需要释放不再需要的连接时非常有用,避免资源浪费。
    • 使用 QSqlDatabase::addDatabase() 时指定唯一连接名,避免重复创建连接。
    • 及时调用 close() 释放资源。

QSqlQuery类

QSqlQuery 类是 Qt 数据库模块中用于执行 SQL 查询和命令的主要类之一。它允许我们向数据库发送 SQL 查询语句,并处理返回的结果。

1. 创建 QSqlQuery 对象

  • 可以使用 QSqlQuery 的构造函数创建一个查询对象,然后使用该对象执行 SQL 查询和命令:
    cpp
    QSqlQuery query;

2. 执行 SQL 查询和命令

  • 一旦创建了 QSqlQuery 对象,可以使用 exec() 函数执行 SQL 查询和命令:
    cpp
    bool success = query.exec("SELECT * FROM students");
    这将执行一个 SELECT 查询,并将查询结果存储在 QSqlQuery 对象中。

3. 检索查询结果

  • 可以使用 next() 函数遍历查询结果的每一行,并使用 value() 函数获取每一列的值:
    cpp
    while (query.next()) {
        QString name = query.value(0).toString(); // 获取第一列的值并转换为字符串
        int age = query.value(1).toInt(); // 获取第二列的值并转换为整数
    }

4. 绑定参数

  • 可以使用 bindValue() 函数将值绑定到 SQL 查询中的占位符。这是防止 SQL 注入攻击的一种重要方法:
    cpp
    query.prepare("SELECT * FROM students WHERE name = :name");
    query.bindValue(":name", "John");
    query.exec();
    这里 :name 是一个占位符,bindValue 函数将值 "John" 绑定到该占位符上。

5. 错误处理

  • 可以使用 lastError() 函数来获取最后一个执行错误的详细信息。这对于调试数据库操作非常有用:
    cpp
    if (!query.exec()) {
        qDebug() << "Query error:" << query.lastError().text();
    }
    • 检查 QSqlQuery::lastError() 获取错误信息。
    • 使用 QSqlQuery::prepare() 预编译 SQL 语句防止 SQL 注入。

基本使用步骤

cpp
#include <QsqDatabase>
#include <Qsq1query>
#include <QDebug>

// 1. 添加数据库驱动(以sqlite为例)
QsqDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("mydatabase.db"); // SQLite数据库文件路径

// 2. 打开数据库连接
if (!db.open()) {
    qDebug() << "Error: Failed to connect database." << db.lastError();
    return;
}

// 3. 执行SQL语句
QsqQuery query;
query.exec("CREATE TABLE USers (id INTEGER PRIMARY KEY, name TEXT)");
query.exec("INSERT INTO USers (name) VALUES ('Alice')");

// 4. 查询数据
query.exec("SELECT * FROM users"));
while (query.next()) {
    int id = query.value("id").toInt();
    QString name = query.value("name").toString();
    qDebug() << "User:" << id << name;
}

// 5. 关闭连接
db.close();

事务处理

批量操作时启用事务以提升性能:

cpp
db.transaction(); // 开启事务
// 执行多条SQL语句...
if (success) {
    db.commit(); // 提交事务
} else {
    db.rollback(); // 回滚事务
}

配置不同数据库驱动

MySQL

cpp
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName("localhost");
db.setDatabaseName("testdb");
db.setUserName("root");
db.setPassword("password");

PostgreSQL

cpp
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL");
db.setHostName("localhost");
db.setPort(5432);
db.setDatabaseName("postgres");
db.setUserName("postgres");
db.setPassword("password");

SQLite

cpp
QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
db.setDatabaseName("/path/to/database.db"); // 直接指定文件路径

集成到Qt项目

.pro 文件中添加 SQL 模块依赖:

makefile
QT += sql

知识如风,常伴吾身