Qt表模型示例

时间:2016-06-20 23:03:53

标签: c++ database qt sqlite

我正在查看Qt示例“表模型示例”

在该示例中,connection.h中的createConnection()方法包含以下代码:

static bool createConnection()
{
    QSqlDatabase db = QSqlDatabase::addDatabase("QSQLITE");
    db.setDatabaseName(":memory:");
    if (!db.open()) {...

我在我的代码中复制了这个例子。我不明白有关它的两件事。

  1. 在createConnection()函数结束时销毁局部变量db(请参阅RAII)。由于我的数据库不需要初始化,而且我没有使用“db”变量,因此我无法理解为什么需要此代码。但是,如果我删除它,我的程序无法从我现有的数据库中读取。我希望db的销毁会关闭数据库并使其不可用。但是,由于我没有触及db变量,为什么在我可以访问数据库之前需要创建它然后销毁呢?由于我没有在任何地方使用db变量,并且在我的代码被调用之前它被销毁,我无法理解为什么我需要调用createConnection()函数。另一方面,我没有看到如何打开数据库并导致变量销毁具有异常安全的RAII代码。

  2. 我从来没有让db.open()失败。如果我没有数据库,则创建它然后打开一个空白数据库。如果我有数据库,则打开它。我有一个数据库,如果由于任何原因它无法打开,我不希望它创建,我想要一个错误,因为一些严重的错误。打开一个空白的数据库只会给我带来麻烦。我该如何处理这个案子?

  3. 我是Qt的新手,但在C ++方面经验丰富。这段代码对我来说没什么意义。我希望db变量的生命周期是open数据库的生命周期。如示例中所编码,我无法看到此代码如何没有资源泄漏。据我所知,初始化db会打开某种全局资源,即使在db变量被销毁导致泄漏之后也会保持打开状态。

    这非常令人困惑。

    THX。

    H Os Tile

2 个答案:

答案 0 :(得分:0)

这只是一个小例子。

  1. QSqlDatabase::addDatabase("QSQLITE");将创建默认连接,任何后续查询都将使用该连接,而不是显式命名另一个连接。在范围结束时,连接不会被销毁。在此示例中,createConnection()将用于初始化inMemory数据库。稍后可以使用QSqlDatabase::database()检索连接。在标准应用程序中,可能会将QSqlDatabase db保留为类成员。

  2. 使用inMemory db只会创建一个空数据库,就像基于SQLite文件的数据库一样。如果要检查现有文件(db),请使用QFile::exists(QString path)

  3. 如果要打开许多数据库(在QSqlDatabase::addDatabase("QSQLITE","anotherConnectionName");上使用不同的连接名称,则会发生泄漏。否则您只是覆盖默认的数据库连接.QApplication本身将保留连接。可以使用它们显式删除它们QSqlDatabase::removeDatabase();

答案 1 :(得分:0)

QSqlDatabase是一个相当奇怪的课程。阅读其文档。连接仍然存在,QSqlDatabase是它的句柄。连接已命名,addDatabase返回具有给定名称的连接,如果不存在,则可选择创建连接。您可以使用任意数量的QSqlDatabase个对象代表一个连接。

由于sqlite内存数据库特定于您的进程,因此在您要求时不创建一个数据库是非常重要的。提前创建它的唯一方法是直接在您的进程中使用sqlite api。这些数据库不会持久存在。这里的行为是非常明智的。