MyTetra Share
Делитесь знаниями!
Работа с базами данных в Qt
Время создания: 20.03.2016 22:41
Текстовые метки: программирование, qt4, qt software, базы данных, sql, c++
Раздел: Компьютер - Программирование - Язык C++ (Си++) - Библиотека Qt - Базы данных
Запись: xintrea/mytetra_syncro/master/base/0000000768/text.html на raw.github.com

Qt дает возможность создания платформо-независимых приложений для работы с базами данных, используя стандартные СУБД. Qt включает «родные» драйвера для Oracle, Microsoft SQL Server, Sybase Adaptive Server, IBM DB2, PostgreSQL, MySQL и ODBC-совместимых баз данных. Qt включает специфичные для баз данных виджеты, а также поддерживает расширение для работы с базами данных любых встроенных или отдельно написанных виджетов.

Введение

Работа с базами данных в Qt происходит на различных уровнях:

1.Слой драйверов — Включает классы QSqlDriver, QSqlDriverCreator, QSqlDriverCreatorBase, QSqlDriverPlugin и QSqlResult. Этот слой предоставляет низкоуровневый мост между определенными базами данных и слоем SQL API.

2.Слой SQL API — Этот слой предоставляет доступ к базам данных. Соединения устанавливаются с помощью класса QSqlDatabase. Взаимодействие с базой данных осуществляется с помощью класса QSqlQuery. В дополнение к классам QSqlDatabase и QSqlQuery слой SQL API опирается на классы QSqlError, QSqlField, QSqlIndex и QsqlRecord.

3.Слой пользовательского интерфейса — Этот слой связывает данные из базы данных с дата-ориентироваными виджетами. Сюда входят такие классы, как QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel.

Соединение с базой данных

Чтобы получить доступ к базе данных с помощью QSqlQuery и QSqlQueryModel, необходимо создать и открыть одно или более соединений с базой данных.

Qt может работать со следующими базами данных (из-за несовместимости с GPL лицензией, не все плагины поставляются с Qt Open Source Edition):

  • QDB2 — IBM DB2 (версия 7.1 и выше
  • QIBASE — Borland InterBase
  • QMYSQL — MySQL
  • QOCI — Драйвер Oracle Call Interface
  • QODBC — Open Database Connectivity (ODBC) — Microsoft SQL Server и другие ODBC-совместимые базы данных
  • QPSQL — PostgreSQL (версия 7.3 и выше)
  • QSQLITE2 — SQLite версии 2
  • QSQLITE — SQLite версии 3
  • QTDS — Драйвер Sybase Adaptive Server

Для сборки плагина драйвера, которые не входят в поставку Qt нужно иметь соответствующую клиентскую библиотеку для используемой СУБД.

Соединиться с базой данных можно вот так:

QSqlDatabase db = QsqlDatabase::addDatabase("QMYSQL", "mydb");

db.setHostName("bigblue");

db.setDatabaseName("flightdb");

db.setUserName("acarlson");

db.setPassword("1uTbSbAs");

bool ok = db.open();

Первая строка создает объект соединения, а последняя открывает его. В промежутке инициализируется некоторая информация о соединении, включая имя соединения, имя базы данных, имя узла, имя пользователя, пароль. В этом примере происходит соединение с базой данных MySQL flightdb на узле bigblue. Аргумент «QMYSQL» в addDatabase() указывает тип драйвера базы данных, чтобы использовать для соединения, а «mydb» — имя соединения.

Как только соединение установлено, можно вызвать статическую функцию QSqlDatabase::database() из любого места программы с указанием имени соединения, чтобы получить указатель на это соединение. Если не передать имя соединения, она вернет соединение по умолчанию.

Если open() потерпит неудачу, он вернет false. В этом случае, можно получить информацию об ошибке, вызвав QSqlDatabase::lastError().

Для удаления соединения с базой данных, надо сначала закрыть базу данных с помощью QSqlDatabase::close(), а затем, удалить соединение с помощью статического метода QSqlDatabase::removeDatabase().

Выполнение инструкций SQL

Класс QSqlQuery обеспечивает интерфейс для выполнения SQL запросов и навигации по результирующей выборке. Для выполнения SQL запросов, просто создают объект QSqlQuery и вызывают QSqlQuery::exec(). Например, вот так:

QSqlQuery query;

query.exec("SELECT name, salary FROM employee WHERE salary > 50000");

Конструктор QSqlQuery принимает необязательный аргумент QSqlDatabase, который уточняет, какое соединение с базой данных используется. Если его не указать, то используется соединение по умолчанию. Если возникает ошибка, exec() возвращает false. Доступ к ошибке можно получить с помощью QSqlQuery::lastError().

QSqlQuery предоставляет единовременный доступ к результирующей выборке одного запроса. После вызова exec(), внутренний указатель QSqlQuery указывает на позицию перед первой записью. Если вызвать метод QSqlQuery::next() один раз, то он переместит указатель к первой записи. После этого необходимо повторять вызов next(), чтобы получать доступ к другим записям, до тех пор пока он не вернет false.

Вот типичный цикл, перебирающий все записи по порядку:

while (query.next()) {

QString name = query.value(0).toString();

int salary = query.value(1).toInt();

qDebug() << name << salary;

}

QSqlQuery может выполнять не только SELECT, но также и любые другие запросы. Следующий пример вставляет запись в таблицу, используя INSERT:

QSqlQuery query;

query.exec("INSERT INTO employee (id, name, salary) "

"VALUES (1001, 'Thad Beaumont', 65000)");

Если надо одновременно вставить множество записей, то зачастую эффективней отделить запрос от реально вставляемых значений. Это можно сделать с помощью вставки значений через параметры. Qt поддерживает два синтаксиса вставки значений: поименованые параметры и позиционные параметры. В следующем примере показана вставка с помощью поименованного параметра:

QSqlQuery query;

query.prepare("INSERT INTO employee (id, name, salary) "

"VALUES (:id, :name, :salary)");

query.bindValue(":id", 1001);

query.bindValue(":name", "Thad Beaumont");

query.bindValue(":salary", 65000);

query.exec();

В этом примере показана вставка с помощью позиционного параметра:

QSqlQuery query;

query.prepare("INSERT INTO employee (id, name, salary) "

"VALUES (?, ?, ?)");

query.addBindValue(1001);

query.addBindValue("Thad Beaumont");

query.addBindValue(65000);

query.exec();

При вставке множества записей требуется вызвать QSqlQuery::prepare() только однажды. Далее можно вызвать bindValue() или addBindValue() с последующим вызовом exec() столько раз, сколько потребуется.

Отображение данных в таблице-представлении

Классы QSqlQueryModel, QSqlTableModel и QSqlRelationalTableModel могут использоваться в качестве источников данных для классов представлений Qt, таких как QListView, QTableView и QTreeView. На практике наиболее часто используется QTableView в связи с тем, что результирующая SQL выборка, по существу, представляет собой двумерную структуру данных.

В следующем примере создается представление основанное на модели данных SQL:

QSqlTableModel model;

model.setTable("employee");

QTableView *view = new QTableView;

view->setModel(model);

view->show();

Если модель является моделью для чтения-записи (например, QSqlTableModel), то представление позволяет редактировать поля. Это можно отключить с помощью следующего кода

view->setEditTriggers(QAbstractItemView::NoEditTriggers);

Можно использовать одну и ту-же модель в качестве источника данных для нескольких представлений. Если пользователь изменяет данные модели с помощью одного из представлений, другие представления немедленно отобразят изменения.

Классы-представления для обозначения колонок наверху отображают заголовки. Для изменения текста заголовка, используется функция setHeaderData() модели. Например:

model->setHeaderData(0, Qt::Horizontal, QObject::tr("ID"));

model->setHeaderData(1, Qt::Horizontal, QObject::tr("Name"));

model->setHeaderData(2, Qt::Horizontal, QObject::tr("City"));

model->setHeaderData(3, Qt::Horizontal, QObject::tr("Country"));

Заключение

В данной статье изложены базовые принципы работы с базами данных в Qt. Однако кроме указанных здесь возможностей еще много интересного, например, транзакции, работа с внешними ключами или создание дата-ориентированых форм. К сожалению эти темы достаточно обширны для одной статьи.

 
MyTetra Share v.0.59
Яндекс индекс цитирования