Использование классов-моделей SQLВ дополнение к QSqlQuery Qt предлагает три высокоуровневых класса для работы с базами данных. Это классы QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel.
Эти классы происходят от QAbstractTableModel (который происходит от QAbstractItemModel) и могут существенно облегчить представление данных из базы данных в элементно-ориентированных классах таких, как QListView и QTableView. Это подробно объясняется в разделе Отображение данных в таблице-представлении. Другое преимущество использования этих классов состоит в том, что они облегчают приспособление кода к другому источнику данных. Например, если вы использовали QSqlTableModel, а затем решили вместо базы данных использовать XML-файлы для хранения данных, то изменение кода - это вопрос замены одной модели данных на другую. Использование модели запроса SQLQSqlQueryModel предлагает основанную на 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 для установки запроса (например, подготовленные запросы QSqlQuery::prepare()). Модель таблицы SQLQSqlTableModel предлагает модель для чтения и записи, которая работает одновременно только с одной таблицей 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(). Есть два нюанса:
Модель реляционной таблицы SQLQSqlRelationalTableModel расширяет QSqlTableModel для предоставления поддержки внешних ключей. Внешний ключ - это связь один-к-одному, установленная между полем одной таблицы и полем первичного ключа другой таблицы. Например, если таблица 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. |
Попытка перевода Qt документации. Если есть желание присоединиться, или если есть замечания или пожелания, то заходите на форум: Перевод Qt документации на русский язык... Люди внесшие вклад в перевод: Команда переводчиков |