Verwendung der SQL-Modell-Klassen

Zusätzlich zu QSqlQuery bietet Qt drei übergeordnete Klassen für den Zugriff auf Datenbanken. Diese Klassen sind QSqlQueryModel, QSqlTableModel, und QSqlRelationalTableModel.

QSqlQueryModelEin Nur-Lese-Modell, das auf einer beliebigen SQL-Abfrage basiert.
QSqlTableModelEin Lese-Schreib-Modell, das mit einer einzelnen Tabelle arbeitet.
QSqlRelationalTableModelEine QSqlTableModel Unterklasse mit Fremdschlüsselunterstützung.

Diese Klassen leiten sich von QAbstractTableModel ab (die wiederum von QAbstractItemModel erbt) und erleichtern die Darstellung von Daten aus einer Datenbank in einer Item-View-Klasse wie QListView und QTableView. Dies wird im Abschnitt " Darstellung von Daten in einer Tabellenansicht " ausführlich erläutert.

Ein weiterer Vorteil der Verwendung dieser Klassen besteht darin, dass sich Ihr Code leichter an andere Datenquellen anpassen lässt. Wenn Sie z. B. QSqlTableModel verwenden und später beschließen, statt einer Datenbank XML-Dateien zum Speichern von Daten zu verwenden, ist es im Grunde nur eine Frage des Ersetzens eines Datenmodells durch ein anderes.

Das SQL-Abfragemodell

QSqlQueryModel bietet ein Nur-Lese-Modell, das auf einer SQL-Abfrage basiert.

Beispiel:

    QSqlQueryModel model; model.setQuery("SELECT * FROM employee"); for(int i = 0; i < model.rowCount();++i) { int id = model.record(i).value("id").toInt();        QString name = model.record(i).value("name").toString();        qDebug() << id << name;
    }

Nachdem Sie die Abfrage mit QSqlQueryModel::setQuery() eingestellt haben, können Sie QSqlQueryModel::record(int) verwenden, um auf die einzelnen Datensätze zuzugreifen. Sie können auch QSqlQueryModel::data() und eine der anderen von QAbstractItemModel geerbten Funktionen verwenden.

Es gibt auch eine setQuery()-Überladung, die ein QSqlQuery -Objekt nimmt und auf dessen Ergebnismenge arbeitet. Dadurch können Sie alle Funktionen von QSqlQuery verwenden, um die Abfrage einzurichten (z. B. vorbereitete Abfragen).

Das SQL-Tabellenmodell

QSqlTableModel bietet ein Lese- und Schreibmodell, das jeweils mit einer einzelnen SQL-Tabelle arbeitet.

Beispiel:

    QSqlTableModel model; model.setTable("employee"); model.setFilter("salary > 50000"); model.setSort(2, Qt::DescendingOrder); model.select(); for(int i = 0; i < model.rowCount();++i) { QString name = model.record(i).value("name").toString(); int salary = model.record(i).value("salary").toInt();        qDebug() << name << salary;
    }

QSqlTableModel ist eine High-Level-Alternative zu QSqlQuery zum Navigieren und Ändern einzelner SQL-Tabellen. Sie führt in der Regel zu weniger Code und erfordert keine Kenntnisse der SQL-Syntax.

Verwenden Sie QSqlTableModel::record(), um eine Zeile in der Tabelle abzurufen, und QSqlTableModel::setRecord(), um die Zeile zu ändern. Der folgende Code erhöht zum Beispiel das Gehalt jedes Mitarbeiters um 10 Prozent:

    for (int i = 0; i < model.rowCount(); ++i) {
        QSqlRecord record = model.record(i);
        double salary = record.value("salary").toInt();
        salary *= 1.1;
        record.setValue("salary", salary);
        model.setRecord(i, record);
    }
    model.submitAll();

Sie können auch QSqlTableModel::data() und QSqlTableModel::setData() verwenden, die von QAbstractItemModel geerbt werden, um auf die Daten zuzugreifen. So aktualisieren Sie zum Beispiel einen Datensatz mit setData():

    model.setData(model.index(row, column), 75000);
    model.submitAll();

So fügen Sie eine Zeile ein und füllen sie auf:

    model.insertRows(row, 1);
    model.setData(model.index(row, 0), 1013);
    model.setData(model.index(row, 1), "Peter Gordon");
    model.setData(model.index(row, 2), 68500);
    model.submitAll();

So löschen Sie fünf aufeinanderfolgende Zeilen:

    model.removeRows(row, 5);
    model.submitAll();

Das erste Argument von QSqlTableModel::removeRows() ist der Index der ersten zu löschenden Zeile.

Wenn Sie die Änderung eines Datensatzes abgeschlossen haben, sollten Sie immer QSqlTableModel::submitAll() aufrufen, um sicherzustellen, dass die Änderungen in die Datenbank geschrieben werden.

Wann und ob Sie submitAll() tatsächlich aufrufen müssen, hängt von der Tabelle edit strategy ab. Die Standardstrategie ist QSqlTableModel::OnRowChange, die festlegt, dass anstehende Änderungen in die Datenbank übernommen werden, wenn der Benutzer eine andere Zeile auswählt. Andere Strategien sind QSqlTableModel::OnManualSubmit (wo alle Änderungen im Modell zwischengespeichert werden, bis Sie submitAll() aufrufen) und QSqlTableModel::OnFieldChange (wo keine Änderungen zwischengespeichert werden). Diese Strategien sind vor allem nützlich, wenn QSqlTableModel mit einer Ansicht verwendet wird.

QSqlTableModel::OnFieldChange scheint das Versprechen einzulösen, dass Sie submitAll() nie explizit aufrufen müssen. Allerdings gibt es zwei Fallstricke:

  • Ohne Zwischenspeicherung kann die Leistung erheblich sinken.
  • Wenn Sie einen Primärschlüssel ändern, kann Ihnen der Datensatz durch die Lappen gehen, während Sie versuchen, ihn auszufüllen.

Das relationale SQL-Tabellenmodell

QSqlRelationalTableModel erweitert QSqlTableModel und bietet Unterstützung für Fremdschlüssel. Ein Fremdschlüssel ist eine 1:1-Zuordnung zwischen einem Feld in einer Tabelle und dem Primärschlüsselfeld einer anderen Tabelle. Wenn zum Beispiel eine Tabelle book ein Feld namens authorid hat, das auf das Feld id der Tabelle author verweist, ist authorid ein Fremdschlüssel.

Der Screenshot links zeigt ein einfaches QSqlTableModel in einer QTableView. Fremdschlüssel (city und country) werden nicht in menschenlesbare Werte aufgelöst. Der Screenshot auf der rechten Seite zeigt eine QSqlRelationalTableModel mit Fremdschlüsseln, die in von Menschen lesbare Textstrings aufgelöst werden.

Der folgende Codeschnipsel zeigt, wie die QSqlRelationalTableModel eingerichtet wurde:

    model->setTable("employee");

    model->setRelation(2, QSqlRelation("city", "id", "name"));
    model->setRelation(3, QSqlRelation("country", "id", "name"));

Einzelheiten finden Sie in der Dokumentation QSqlRelationalTableModel.

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.