正确使用 QSqlDatabase 与 QSqlQuery 的方法

发布于:2024-06-23 ⋅ 阅读:(166) ⋅ 点赞:(0)

前言

在使用 Qt 的数据库模块时,许多人可能会对 QSqlDatabase 和 QSqlQuery 的使用方法感到困惑。本文将对这一话题进行详细讨论,并提供一些最佳实践。

基本使用示例

首先,让我们看看以下代码片段:

{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLDRIVER");
    QSqlQuery query(db);
    query.exec("your SQL statement here");
}

QSqlDatabase::removeDatabase("default_connection_name");

根据文档说明,当 querydb 对象超出作用域时,它们会自动析构。但这种方式是否高效呢?如果将 db 缓存到一个类中,又该如何处理?

在类中缓存 QSqlDatabase

下面我们提供一个示例类,将 QSqlDatabase 缓存其中:

class Dummy {
public:
    Dummy() { 
        db = QSqlDatabase::addDatabase("QSQLDRIVER", "connection-name");
    }
    ~Dummy() {
        db.close();
    }

    bool run() {
        QSqlQuery query(db);
        bool retval = query.exec("your SQL statement here");
        // 其他操作...
        return retval;
    }

private:
    QSqlDatabase db;
};

在使用上述类时,有时可能会看到如下警告:

QSqlDatabasePrivate::removeDatabase: connection 'BLABLA' is still in use, all queries will cease to work.

这提示即使没有调用 run() 方法,连接也可能依然存在问题。

最佳实践

当你使用 QSqlDatabase::addDatabaseQSqlDatabase::removeDatabase 时,其实只是将数据库连接信息(如驱动、主机名、端口、数据库名、用户名和密码)关联或解除关联一个名字而已(如果没有指定连接名,则使用默认连接名)。

全局单一实例

以下为两种推荐的使用方式:

方法一:全局单例数据库实例

这种方法适用于你希望数据库连接在整个应用程序生命周期内保持打开状态的情况。

// 在应用程序生命周期内存储 QSqlDatabase 实例的对象中
QSqlDatabase db;

void initializeDatabase() {
    db = QSqlDatabase::addDatabase("QMYSQL", "connection-name");
    db.setHostName("hostname");
    db.setDatabaseName("database");
    db.setUserName("username");
    db.setPassword("password");
    if (!db.open()) {
        // 处理错误
    }
}

void useDatabase() {
    QSqlDatabase db = QSqlDatabase::database("connection-name");
    QSqlQuery query(db);
    // 使用 query 对象执行 SQL 操作
}
方法二:每次使用时打开和关闭连接

这种方法适用于按需打开数据库连接的情况。

void executeQuery() {
    {
        QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL", "connection-name");
        db.setHostName("hostname");
        db.setDatabaseName("database");
        db.setUserName("username");
        db.setPassword("password");
        if (!db.open()) {
            // 处理错误
        }
        // db 在作用域结束时关闭
    }

    {
        QSqlDatabase db = QSqlDatabase::database("connection-name");
        QSqlQuery query(db);
        // 使用 query 对象执行 SQL 操作
    }
}

注意事项

在多重适用数据库连接的情况下,建议不要显式调用 close() 方法,因为你可能有多个对象在重入使用相同的数据库连接(如函数 A 使用连接并调用函数 B,而 B 也使用相同的连接。如果 B 在返回给 A 前关闭了连接,则对 A 来说,该连接也会被关闭,这通常不是期望的行为)。

结论

按照上述方法管理和使用 QSqlDatabaseQSqlQuery,可以避免常见的连接问题。同时,根据具体需求选择合适的连接管理策略,也能提升应用程序的稳定性和性能。明显的方法是确保在所有查询都完全停止之前不关闭数据库连接。


网站公告

今日签到

点亮在社区的每一天
去签到