Auf dieser Seite

Verwendung der SQL-Modellklassen

Neben ` QSqlQuery` bietet Qt drei übergeordnete Klassen für den Zugriff auf Datenbanken. Diese Klassen sind ` QSqlQueryModel`, ` QSqlTableModel` und ` QSqlRelationalTableModel`.

QSqlQueryModelEin schreibgeschütztes Modell, das auf einer beliebigen SQL-Abfrage basiert.
QSqlTableModelEin Lese-/Schreib-Modell, das mit einer einzelnen Tabelle arbeitet.
QSqlRelationalTableModelEine Unterklasse von „ QSqlTableModel “ mit Unterstützung für Fremdschlüssel.

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

Ein weiterer Vorteil der Verwendung dieser Klassen besteht darin, dass sich Ihr Code dadurch leichter an andere Datenquellen anpassen lässt. Wenn Sie beispielsweise QSqlTableModel verwenden und sich später entscheiden, Daten statt in einer Datenbank in XML-Dateien zu speichern, müssen Sie im Grunde nur das eine Datenmodell durch das andere ersetzen.

Das SQL-Abfragemodell

QSqlQueryModel bietet ein schreibgeschütztes 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()` festgelegt haben, können Sie mit ` QSqlQueryModel::record(int)` auf die einzelnen Datensätze zugreifen. Sie können auch ` QSqlQueryModel::data()` und alle anderen Funktionen verwenden, die von ` QAbstractItemModel` geerbt wurden.

Es gibt zudem eine Überladung von ` setQuery()` (), die ein ` QSqlQuery `-Objekt entgegennimmt und auf dessen Resultset arbeitet. Dies ermöglicht es Ihnen, beliebige Funktionen von ` QSqlQuery ` zum Einrichten der Abfrage zu nutzen (z. B. vorbereitete Abfragen).

Das SQL-Tabellenmodell

QSqlTableModel bietet ein Lese-Schreib-Modell, das jeweils auf eine einzelne SQL-Tabelle angewendet wird.

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 hochrangige Alternative zu ` QSqlQuery ` für die Navigation und Bearbeitung einzelner SQL-Tabellen. Sie führt in der Regel zu weniger Code und erfordert keine Kenntnisse der SQL-Syntax.

Verwenden Sie ` QSqlTableModel::record()` zum Abrufen einer Zeile aus der Tabelle und ` QSqlTableModel::setRecord()` zum Ändern der Zeile. Der folgende Code erhöht beispielsweise 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 die von ` QAbstractItemModel` geerbten Methoden ` QSqlTableModel::data()` und ` QSqlTableModel::setData()` verwenden, um auf die Daten zuzugreifen. So aktualisieren Sie beispielsweise einen Datensatz mit ` setData()`:

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

So fügen Sie eine Zeile ein und füllen diese mit Daten:

    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 Bearbeitung 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 ` edit strategy`-Einstellung der Tabelle ab. Die Standardstrategie ist ` QSqlTableModel::OnRowChange`, was bedeutet, dass ausstehende Änderungen in die Datenbank übernommen werden, sobald der Benutzer eine andere Zeile auswählt. Weitere Strategien sind „ QSqlTableModel::OnManualSubmit “ (bei dem alle Änderungen im Modell zwischengespeichert werden, bis Sie `submitAll()` aufrufen) und „ QSqlTableModel::OnFieldChange “ (bei dem keine Änderungen zwischengespeichert werden). Diese sind vor allem dann nützlich, wenn „ QSqlTableModel “ in Verbindung mit einer Ansicht verwendet wird.

QSqlTableModel::OnFieldChange scheint das Versprechen einzulösen, dass man `submitAll()` nie explizit aufrufen muss. Es gibt jedoch zwei Fallstricke:

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

Das relationale SQL-Tabellenmodell

QSqlRelationalTableModel erweitert „ QSqlTableModel “, um Unterstützung für Fremdschlüssel zu bieten. Ein Fremdschlüssel ist eine 1:1-Zuordnung zwischen einem Feld in einer Tabelle und dem Primärschlüsselfeld einer anderen Tabelle. Wenn beispielsweise die Tabelle „ book “ ein Feld namens „ authorid “ enthält, das auf das Feld „ id “ der Tabelle „author“ verweist, sagen wir, dass „ authorid “ ein Fremdschlüssel ist.

Tabelle, in der Stadt und Land als numerische Fremdschlüsselwerte angegeben sindTabelle mit Städten und Ländern, die in Textzeichenfolgen umgewandelt wurden

Der Screenshot auf der linken Seite zeigt eine einfache „ QSqlTableModel “ in einer „ QTableView “. Fremdschlüssel (city und country) werden nicht in für Menschen lesbare Werte aufgelöst. Der Screenshot auf der rechten Seite zeigt eine „ QSqlRelationalTableModel “, bei der Fremdschlüssel in für Menschen lesbare Textzeichenfolgen aufgelöst wurden.

Der folgende Codeausschnitt zeigt, wie die „ QSqlRelationalTableModel “ eingerichtet wurde:

    model->setTable("employee");

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

Weitere Informationen finden Sie in der Dokumentation zu „ QSqlRelationalTableModel “.

© 2026 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.