Qt厚数据库客户端架构

时间:2010-08-19 16:30:14

标签: model-view-controller qt architecture coding-style qtableview

我的目标是为数据库创建一个胖客户端。基本上它只是管理三个数据列表。

我想将我的应用程序分割成分离的层,因此使用Qt的Model / View框架对我来说似乎很自然。

  • 我应该何时创建QSql *模型实例?

我需要能够多次连接/断开数据库(我有菜单项)。我不满意删除一堆模型并在每次连接/断开连接时再次创建它们。

有没有替代方法?

  • 我应该在哪里创建QSql * Model实例?

我不认为MainWindow或任何其他与GUI相关的类应该保存这样的代码:

m_goodsModel->setRelation(1, QSqlRelation("Level", "LevelId", "Name"));

我想将GUI与数据结构分离。任何想法如何做到这一点?

  • 我应该何时何地将我的观点与模型绑定?

我需要以十几种方式代表我的三个清单。如果每次连接/断开连接时都重新创建模型,我需要再次将新创建的模型注入所有视图。

如果我只能这样做一次会很棒,但我不知道如何。

  • 如何处理讨厌的QSqlTableModel::select()方法?

这个让我发疯。与其他模型(例如QStringListModelQFileSystemModel等)相比,数据可以立即使用,从QSqlTableModel派生的模型在您手动调用select()之前是无用的。 1}}方法。在该调用之前,模型为空,以便使用该模型的视图;标题数据也没有填充,因此视图甚至不知道它必须呈现哪些列。

由于我无法避免select()调用,我想知道我应该把它放在哪里以便它适合它?我不认为MainWindow或任何其他与GUI相关的类应该包含该代码。

  • 性能和稳健性

我不乐意在db重新连接时重新初始化所有内容。这样做需要很长时间(我的意思是在执行期间)。我还希望在模型重新创建过程中避免崩溃,因为视图仍然可以引用它们。

有没有其他方法可以只设置一次并正常处理重新连接?

1 个答案:

答案 0 :(得分:1)

在我看来,所有这些问题的直接答案是将所有与数据库相关的操作包装在专用类中,并在MainWindow / Dialog /中保存指向此类实例的指针。

可能的设计可能是这样的:

class DatabaseAccess : public QObject
{
       Q_OBJECT
    public:
       void connectToDatabase(const QString & hostname, const QString & db, const QString & user, const QString & password);
       void disconnectFromDatabse();

       QAbstractItemModel * getModelForX();
       QAbstractItemModel * getModelForY();

    private:
       QSqlTableModel * modelForX;
       QSqlRelationalTableModel * modelForY;
}

此处,X和Y只是您应用程序中查询类型的占位符。

您可以在connectToDatabase()中创建模型,并在getModelForX / Y方法中需要新数据时调用select()

据我所知,您不能继续使用具有不同数据库连接的相同模型实例,因为QSqlTableModel及其死者绑定到QSqlDatabase实例。成功连接后,您需要刷新视图。