gpt4 book ai didi

database - QSqlDatabase & QSqlQuery 的正确方法是什么?

转载 作者:太空狗 更新时间:2023-10-30 01:39:10 36 4
gpt4 key购买 nike

我对手册感到困惑,我应该这样工作吗:

{
QSqlDatabase db = QSqlDatabase::addDatabase (...);
QSqlQuery query (db);
query.exec (...);
}

QSqlDatabase::removeDatabase (...);

正如文档指出的那样,querydb 将被自动解构。但这有效率吗?

好吧,如果我在类中缓存 db,如下所示:

class Dummy {
Dummy() {
db = QSqlDatabase::addDatabase (...);
}
~Dummy() {
db.close();
}

bool run() {
QSqlQuery query (db);
bool retval = query.exec (...);
blabla ...
}

private:
QSqlDatabase db;
};

有时我会看到如下警告:

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

即使我没有调用 run()

最佳答案

当您创建 QSqlDatabase对象 addDatabase或者当您调用 removeDatabase ,您只是将元组(驱动程序,主机名:端口,数据库名称,用户名/密码)关联或取消关联到名称(如果未指定连接名称,则为默认连接名称) .
SQL驱动被实例化,但是数据库只会在你调用QSqlDatabase::open时打开。 .

该连接名称是在应用程序范围内定义的。所以如果你调用addDatabase在使用它的每个对象中,您正在更改所有 QSqlDatabase使用相同连接名称并使所有在其上处于事件状态的查询无效的对象。

您引用的第一个代码示例展示了如何正确解除连接名称的关联,方法是确保:

  • 全部QSqlQueryQSqlDatabase 分离在调用 QSqlQuery::finish() 关闭数据库之前, 当 QSqlQuery 时是自动的对象超出范围,
  • 全部QSqlDatabase具有相同连接名称的是 close() d 当你打电话时 QSqlDatabase::removeDatabase (当 close() 对象超出范围时,也会自动调用 QSqlDatabase

当您创建 QSqlDatabase 时,根据您是希望连接在应用程序生命周期 (1) 中保持打开状态还是仅在需要时 (2) 保持打开状态,您可以:

  1. 保留一个 QSqlDatabase在一个类中实例化(例如,在您的主窗口中),并通过传递 QSqlDatabase 在其他需要它的对象中使用它直接或只是您传递给 QSqlDatabase::database 的连接名称得到QSqlDatabase实例返回。 QSqlDatabase::database使用 QHash检索 QSqlDatabase从它的名字来看,所以它可能比通过 QSqlDatabase 慢得可以忽略不计object 直接在对象和函数之间,如果你使用默认连接,你甚至不必在任何地方传递任何东西,只需调用 QSqlDatabase::database()没有任何参数。

    // In an object that has the same lifetime as your application
    // (or as a global variable, since it has almost the same goal here)
    QSqlDatabase db;

    // In the constructor or initialization function of that object
    db = QSqlDatabase::addDatabase("QSQLDRIVER", "connection-name");
    db.setHostname(...);
    // ...
    if(!this->db.open()) // open it and keep it opened
    {
    // Error handling...
    }

    // --------
    // Anywhere you need it, you can use the "global" db object
    // or get the database connection from the connection name
    QSqlDatabase db = QSqlDatabase::database("connection-name");
    QSqlQuery query(db);
  2. 配置QSqlDatabase一次,打开它测试参数是否正确,然后放弃该实例。连接名称仍然可以在任何地方访问,但必须重新打开数据库:

    {
    // Allocated on the stack
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLDRIVER", "connection-name");
    db.setHostname(...);
    // ...
    if(!this->db.open()) // test the connection
    {
    // Error handling
    }
    // db is closed when it goes out of scope
    }

    {
    // Same thing as for (1), but by default database() opens
    // the connection if it isn't already opened
    QSqlDatabase db = QSqlDatabase::database("connection-name");
    QSqlQuery query(db);

    // if there is no other connection open with that connection name,
    // the connection is closed when db goes out of scope
    }

    在那种情况下,请注意您不应该显式关闭数据库,因为您可以有多个对象以可重入的方式使用同一个数据库连接(例如,如果函数 A 使用该连接并调用 B,后者也使用连接。如果 B 在将控制权返回给 A 之前关闭连接,则 A 的连接也将关闭,这可能是一件坏事)。

关于database - QSqlDatabase & QSqlQuery 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7669987/

36 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com