- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
QT 4: программирование GUI на С++ - Жасмин Бланшет
Шрифт:
Интервал:
Закладка:
Во-первых, мы вызываем функцию QSqlDatabase::addDatabase() для создания объекта QSqlDatabase. Первый аргумент функции addDatabase() задает драйвер базы данных, который Qt должна использовать для доступа к базе данных. В данном случае мы используем MySQL (??? — в коде QOCI, Oracle Call Interface).
Затем мы устанавливаем имя хоста базы данных, имя базы данных, имя пользователя и пароль, и мы открываем соединение. Если функция open() завершается неудачей, мы выводим сообщение об ошибке, используя QSqlError::showMessage().
Обычно функцию createConnection() вызывают в main():
01 int main(int argc, char *argv[])
02 {
03 QApplication app(argc, argv);
04 if (!createConnection())
05 return 1;
06 return app.exec();
07 }
После установки соединения мы можем применять QSqlQuery для выполнения любой инструкции SQL, поддерживаемой используемой базой данных. Ниже приводится пример выполнения команды SELECT:
QSqlQuery query;
query.exec("SELECT title, year FROM cd WHERE year >= 1998");
После вызова функции exec() мы можем просмотреть результат запроса:
while (query.next()) {
QString title = query.value(0).toString();
int year = query.value(1).toInt();
cerr << qPrintable(title) << ": " << year << endl;
}
Мы вызываем функцию next() один раз для позиционирования QSqlQuery на первую запись полученного набора. Последующие вызовы next() продвигают указатель записи на одну позицию дальше, пока не будет достигнут конец, когда функция next() возвращает false. Если результирующий набор (result set) пустой (или запрос завершается неудачей), первый вызов функции next() возвратит false.
Функция value() возвращает значение поля, как QVariant. Поля пронумерованы начиная с 0 в порядке их указания в команде SELECT. Класс QVariant может содержать многие типы С++ и Qt, включая int и QString. Другие типы данных, которые могут храниться в базе данных, преобразуются в соответствующие типы С++ и Qt и хранятся в QVariant. Например, VARCHAR представляется в виде QString, a DATETIME — в виде QDateTime.
Класс QSqlQuery содержит некоторые другие функции для просмотра результирующего набора: first(), last(), previous() и seek(). Эти функции удобны, но для некоторых баз данных они могут выполняться медленнее и расходовать памяти больше, чем функция next(). При работе с большими наборами данных мы можем осуществить простую оптимизацию, вызывая функцию QSqlQuery::setForwardOnly(true) перед вызовом exec(), и только затем использовать next() для просмотра результирующего набора.
Ранее мы задавали запрос SQL в аргументе функции QSqlQuery::exec(), но, кроме того, мы можем передавать его непосредственно конструктору, который сразу же выполнит его:
QSqlQuery query("SELECT title, year FROM cd WHERE year >= 1998");
Мы можем проверить наличие ошибки, вызывая функцию isActive() для запроса:
if (!query.isActive())
QMessageBox::warning(this, tr("Database Error"),
query.lastError().text());
Если ошибки нет, запрос становится «активным» и мы можем использовать next() для перемещения по результирующему набору.
Выполнение команды INSERT осуществляется почти так же просто, как и команды SELECT:
QSqlQuery query("INSERT INTO cd (id, artistid, title, year) "
"VALUES (203, 102, 'Living in America', 2002)");
После этого функция numRowsAffected() возвращает количество строк, которые были изменены инструкцией SQL (или —1, если возникла ошибка).
Если нам необходимо вставлять много записей или если мы хотим избежать преобразования значений в строковые данные (и правильного преобразования специальных символов), мы можем использовать функцию prepare() для указания полей в шаблоне запроса и затем присваивания им необходимых нам значений. Qt поддерживает как стиль Oracle, так и стиль ODBC для всех баз данных, применяя, где возможно, «родной» интерфейс базы данных или имитируя его в противном случае. Ниже приводится пример, в котором используется синтаксис Oracle для представления поименованных полей:
QSqlQuery query;
query.prepare("INSERT INTO cd (id, artistid, title, year) "
"VALUES (:id, :artistid, :title, :year)");
query.bindValue(":id", 203);
query.bindValue(":artistid", 102);
query.bindValue(":title", "Living in America");
query.bindValue(":year", 2002);
query.exec();
Ниже приводится тот же пример позиционного представления полей в стиле ODBC:
QSqlQuery query;
query.prepare("INSERT INTO cd (id, artistid, title, year) "
"VALUES (?, ?, ?, ?)");
query.addBindValue(203);
query.addBindValue(102);
query.addBindValue("Living in America");
query.addBindValue(2002);
query.exec();
После вызова функции exec() мы можем вызвать bindValue() или addBindValue() для присваивания новых значений, затем снова вызвать exec() для выполнения запроса уже с новыми значениями.
Такие шаблоны часто используются для задания двоичных строковых данных, содержащих символы не в коде ASCII или Latin-1. Незаметно для пользователя Qt использует Unicode в тех базах данных, которые поддерживают Unicode, а в тех, которые не делают этого, Qt также незаметно для пользователя преобразует строковые данные в соответствующую кодировку.
Qt поддерживает SQL—транзакции в тех базах данных, где они предусмотрены. Для запуска транзакции мы вызываем функцию transaction() для объекта QSqlDatabase, представляющего соединение с базой данных. Для завершения транзакции мы вызываем либо функцию commit(), либо функцию rollback(). Например, ниже показано, как мы можем найти внешний ключ (foreign key) и выполнить команду INSERT внутри транзакции:
QSqlDatabase::database().transaction();
QSqlQuery query;
query.exec("SELECT id FROM artist WHERE name= 'Gluecifer'");
if (query.next()) {
int artistId = query.value(0).tolnt();
query.exec("INSERT INTO cd (id, artistid, title, year) "
"VALUES (201, " + QString::number(artistId)
+ ", 'Riding the Tiger', 1997)");
}
QSqlDatabase::database().commit();
Функция QSqlDatabase::database() возвращает объект QSqlDatabase, представляющий соединение, созданное нами при вызове createConnection(). Если транзакция не может запуститься, функция QSqlDatabase::transaction() возвращает false. Некоторые базы данных не поддерживают транзакции. В этом случае функции transaction(), commit() и rollback() ничего не делают. Мы можем проверить возможность поддержки базой данных транзакций путем вызова функции hasFeature() для объекта QSqlDriver, связанного с базой данных:
QSqlDriver *driver = QSqlDatabase::database().driver();
if (driver->hasFeature(QSqlDriver::Transactions))
…
Можно проверить наличие в базе данных ряда других возможностей, включая поддержку объектов BLOB (Binary Large Objects — большие двоичные объекты), Unicode и подготовленных запросов.
В приводимых до сих пор примерах мы предполагали, что в приложении используется одно соединение с базой данных. Если мы хотим создать несколько соединений, мы можем передавать название соединения в качестве второго аргумента функции addDatabase(). Например:
QSqlDatabase *db = QSqlDatabase::addDatabase("QPSQL", "OTHER");
db. setHostName("saturn.mcmanamy.edu");
db.setDatabaseName("starsdb");
db.setUserName("hilbert");
db.setPassword("ixtapa7");
Мы можем затем получить указатель на объект QSqlDatabase, передавая название соединения функции QSqlDatabase::database():
QSqlDatabase db = QSqlDatabase::database("OTHER");
Для выполнения запросов с другим соединением мы передаем объект QSqlDatabase конструктору QSqlQuery:
QSqlQuery query(db);
query.exec("SELECT id FROM artist WHERE name = 'Mando Diao'");
Несколько соединений полезны, если мы хотим выполнять одновременно несколько транзакций, поскольку каждое соединение может использоваться только для одной активной транзакции. Когда мы используем несколько соединений с базой данных, мы можем все-таки иметь одно непоименованное соединение и QSqlQuery будет использовать это соединение, если не указано поименованное соединение.
Кроме QSqlQuery Qt содержит класс QSqlTableModel — интерфейс высокого уровня, позволяя нам не использовать выражения SQL «в чистом виде» для выполнения наиболее распространенных SQL—команд (SELECT, INSERT, UPDATE и DELETE). Этот класс может использоваться автономно без какого-либо графического пользовательского интерфейса или в качестве источника данных для QListView или QTableView.
Ниже приводится пример использования QSqlTableModel для выполнения команды SELECT:

