Spec-Zone.ru › Qt 5.11

Использование классов SQL-моделей

В дополнение к QSqlQuery, Qt предлагает три класса более высокого уровня для доступа к базам данных. Этими классами являются QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel.

QSqlQueryModel Модель только для чтения, основанная на произвольном запросе SQL.
QSqlTableModel Модель чтения-записи, работающая с одной таблицей.
QSqlRelationalTableModel Подкласс QSqlTableModel с поддержкой внешних ключей.

Эти классы наследуются от QAbstractTableModel (который, в свою очередь, наследуется от QAbstractItemModel) и упрощают представление данных из базы данных в классе представления элементов, таком как QListView и QTableView. Это подробно описано в разделе Представление данных в представлении таблицы.

Другое преимущество использования этих классов заключается в том, что это может сделать ваш код более адаптивным к другим источникам данных. Например, если вы используете QSqlTableModel, а затем решите использовать XML-файлы для хранения данных вместо базы данных, это фактически сводится к замене одной модели данных другой.

Модель запроса SQL

QSqlQueryModel предлагает модель только для чтения, основанную на запросе SQL.

Пример:

    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;
    }

После установки запроса с помощью QSqlQueryModel::setQuery(), вы можете использовать QSqlQueryModel::record(int) для доступа к отдельным записям. Вы также можете использовать QSqlQueryModel::data() и любые другие функции, унаследованные от QAbstractItemModel.

Также существует перегрузка метода setQuery(), принимающая объект QSqlQuery и работающая с его набором результатов. Это позволяет использовать любые функции QSqlQuery для настройки запроса (например, подготовленные запросы).

Модель таблицы SQL

QSqlTableModel предлагает модель чтения-записи, работающую с одной таблицей SQL за раз.

Пример:

    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 — это высокоуровневая альтернатива QSqlQuery для навигации и изменения отдельных таблиц SQL. Как правило, это приводит к меньшему коду и не требует знания синтаксиса SQL.

Используйте QSqlTableModel::record() для получения строки в таблице и QSqlTableModel::setRecord() для изменения строки. Например, следующий код увеличит зарплату каждого сотрудника на 10 процентов:

    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();

Вы также можете использовать QSqlTableModel::data() и QSqlTableModel::setData(), которые унаследованы от QAbstractItemModel, для доступа к данным. Например, вот как обновить запись с помощью setData():

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

Вот как вставить строку и заполнить ее:

    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();

Вот как удалить пять последовательных строк:

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

Первый аргумент в QSqlTableModel::removeRows() — индекс первой строки для удаления.

После завершения изменения записи всегда вызывайте QSqlTableModel::submitAll(), чтобы убедиться, что изменения сохранены в базе данных.

Необходимость и необходимость вызова submitAll() зависят от стратегии редактирования таблицы. По умолчанию используется стратегия QSqlTableModel::OnRowChange, которая указывает, что ожидаемые изменения применяются к базе данных, когда пользователь выбирает другую строку. Другие стратегии — QSqlTableModel::OnManualSubmit (где все изменения кешируются в модели до вызова submitAll()) и QSqlTableModel::OnFieldChange (где изменения не кешируются). Они в основном полезны при использовании QSqlTableModel с представлением.

QSqlTableModel::OnFieldChange кажется обещающим, что вам никогда не нужно явно вызывать submitAll(). Однако есть две ловушки:

  • Без кэширования производительность может значительно снизиться.
  • Если вы изменяете первичный ключ, запись может ускользнуть от вас во время попытки заполнения.

Модель реляционной таблицы SQL

QSqlRelationalTableModel расширяет QSqlTableModel, чтобы обеспечить поддержку внешних ключей. Внешний ключ — это отображение 1 к 1 между полем в одной таблице и полем первичного ключа другой таблицы. Например, если у таблицы book есть поле, называемое authorid, которое ссылается на поле id таблицы авторов, мы говорим, что authorid является внешним ключом.

На снимке слева показана обычная модель QSqlTableModel в QTableView. Внешние ключи (city и country) не разрешаются в удобочитаемые значения. На снимке справа показана QSqlRelationalTableModel, где внешние ключи разрешаются в удобочитаемые текстовые строки.

Следующий фрагмент кода показывает, как была настроена QSqlRelationalTableModel:

    model->setTable("employee");

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

См. документацию QSqlRelationalTableModel для получения подробных сведений.

© The Qt Company Ltd
Licensed under the GNU Free Documentation License, Version 1.3.
https://doc.qt.io/archives/qt-5.11/sql-model.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API