Технология ООП
Санкт-Петербургский государственный политехнический университет
29 ноября 2011
Технология ООП
Базы данных
Qt обеспечивает интерфейс для общения с базами данных
независящий от платформы и конкретной реализации базы
данных.
Технология ООП
Базы данных
Для использования баз данных, необходимо подключить
модуль QtSql.
Добавить в проектный файл: QT += sql
Для использования классов этого модуля:
#i n c l u d e <QtSql>
Технология ООП
Базы данных
Классы модуля QtSql разделены на 3 уровня:
уровень драйверов
программный уровень
уровень пользовательского интерфейса
Технология ООП
Уровень драйверов
К уровню драйверов относятся классы для получения данных
на физическом уровне: QSqlDriver, QSqlDriverPlugin, QSqlResult.
Технология ООП
Уровень драйверов
Связь с базой данных обеспечивается объектом QSqlDatabase.
Qt включает в себя следующие драйверы:
QDB2 — DB2
QIBASE — Interbase
QMYSQL — MySQL
QOCI — Oracle
QODBC — ODBC драйвер для MS SQL Server, IBM DB2 и
т.д.
QPSQL — PostgreSQL
QSQLITE — PostgreSQL
QTDS — Sybase
Технология ООП
Уровень драйверов
Для выполнения запросов SQL необходимо сначала установить
соединение с базой данных.
Обычно настройка выполняется отдельной функцией
вызываемой при запуске приложения.
bool c r e a t e C o n n e c t i o n ( )
{
QSqlDatabase ∗ db = QSqlDatabase : : a d d D a t a b a s e ( "
QSQLITE" ) ;
db−>setDatabaseName ( " base . dat " ) ;
i f ( ! db−>open ( ) ) { qDebug ( " E r r o r ␣open␣ database " ) ;
return f a l s e ; }
}
При использовании серверов баз данных, необходимо также
задать setHostName, setUserName, setPassword.
Технология ООП
Уровень драйверов
Задав имя соединения, при подключении к базе данных, можно
вернуть на него потом указатель.
QSqlDatabase ∗ db = QSqlDatabase : : a d d D a t a b a s e ( "
QSQLITE" , "MYDATABASE" ) ;
...
QSqlDatabase db1 = QSqlDatabase : : d a t a b a s e ( "
MYDATABASE" ) ;
Технология ООП
Программный уровень
Программный интерфейс для обращения к базе данных:
QSqlDatabase, QSqlQuery, QSqlIndex, QSqlRecord.
Технология ООП
Программный уровень
После установки соединения можно применять класс
QSqlQuery для выполнения любых запросов SQL
поддерживаемых используемой базой данных.
QSqlQuery q u e r y ;
q u e r y . e x e c ( "SELECT␣ country , year ␣FROM␣ a r t i s t " )
После выполнения запроса, можно посмотреть результат:
while ( query . next () ) {
QString country = query . value (0) . t o S t r i n g () ;
int year = query . value (1) . t o I n t () ;
}
Функция next передвигает указатель на следующую
возвращенную запись, когда записей не осталось, либо
возвратилась ошибка, то возвращается false.
Функция value возвращает QVariant на ячейку.
Технология ООП
Программный уровень
Указание полей в шаблоне запроса при операциях вставки
(используя имена):
QSqlQuery q u e r y ;
q u e r y . p r e p a r e ( "INSERT␣INTO␣ person ␣ ( id , ␣forename , ␣
surname ) ␣"
"VALUES␣ ( : id , ␣ : forename , ␣ : surname ) " ) ;
query . bindValue (" : id " , 1001) ;
q u e r y . b i n d V a l u e ( " : forename" , "Bart" ) ;
q u e r y . b i n d V a l u e ( " : surname" , "Simpson" ) ;
query . exec () ;
Технология ООП
Программный уровень
Указание полей в шаблоне запроса при операциях вставки
(используя позиции):
QSqlQuery q u e r y ;
q u e r y . p r e p a r e ( "INSERT␣INTO␣ person ␣ ( id , ␣forename , ␣
surname ) ␣"
"VALUES␣ ( : id , ␣ : forename , ␣ : surname ) " ) ;
query . bindValue (0 , 1001) ;
q u e r y . b i n d V a l u e ( 1 , "Bart" ) ;
q u e r y . b i n d V a l u e ( 2 , "Simpson" ) ;
query . exec () ;
Технология ООП
Программный уровень
Указание полей в шаблоне запроса при операциях вставки
(используя позиции, версия 2):
QSqlQuery q u e r y ;
q u e r y . p r e p a r e ( "INSERT␣INTO␣ person ␣ ( id , ␣forename , ␣
surname ) ␣"
"VALUES␣ ( ? , ␣ ? , ␣ ?) " ) ;
query . bindValue (0 , 1001) ;
q u e r y . b i n d V a l u e ( 1 , "Bart" ) ;
q u e r y . b i n d V a l u e ( 2 , "Simpson" ) ;
query . exec () ;
Технология ООП
Программный уровень
Указание полей в шаблоне запроса при операциях вставки
(используя позиции, версия 3):
QSqlQuery q u e r y ;
q u e r y . p r e p a r e ( "INSERT␣INTO␣ person ␣ ( id , ␣forename , ␣
surname ) ␣"
"VALUES␣ ( ? , ␣ ? , ␣ ?) " ) ;
query . addBindValue (1001) ;
q u e r y . a d d B i n d V a l u e ( "Bart" ) ;
q u e r y . a d d B i n d V a l u e ( "Simpson" ) ;
query . exec () ;
Технология ООП
Программный уровень
Указание полей в шаблоне запроса при операциях вставки
(средствами подстановки Qt):
QSqlQuery q u e r y ;
Q S t r i n g s t r ( "INSERT␣INTO␣ person ␣ ( id , ␣forename , ␣
surname ) ␣VALUES␣(%1,␣%2,␣%3)" ) ;
s t r . arg (1001) ;
s t r . a r g ( "Bart" ) ;
s t r . a r g ( "Simpson" ) ;
query . exec ( s t r ) ;
Технология ООП
Программный уровень
Передача значений в хранимые процедуры в базе данных:
QSqlQuery q u e r y ;
q u e r y . p r e p a r e ( "CALL␣ A s c i i T o I n t ( ? , ␣ ?) " ) ;
q u e r y . b i n d V a l u e ( 0 , "A" ) ;
q u e r y . b i n d V a l u e ( 1 , 0 , QSql : : Out ) ;
query . exec () ;
i n t i = q u e r y . boundValue ( 1 ) . t o I n t ( ) ;
Технология ООП
Программный уровень
Qt поддерживает транзакции в тех базах где они
предусмотрены, для активации транзакции используется
функция transaction() класса QSqlDatabase.
QSqlDatabase : : d a t a b a s e ( ) . t r a n s a c t i o n ( ) ;
QSqlQuery q u e r y ( " s e l e c t ␣ i d ␣from␣ a r t i s t ␣where␣name␣=
␣ ’ Gluecifer ’") ;
i f ( query . next () )
{
int a r t i s t I d = query . value (0) . t o I n t () ;
q u e r y . e x e c ( " i n s e r t ␣ i n t o ␣cd␣ ( id , ␣ a r t i s t i d , ␣ t i t l e , ␣
year ) ␣VALUES␣ (201 , ␣" + Q S t r i n g : : number ( a r t i s t I d
) + " , ␣ ’ R i d i n g ␣ the ␣ Tiger ’ , ␣1997)" ) ;
}
QSqlDatabase : : d a t a b a s e ( ) . commit ( ) ;
Закрепление транзакции осуществляется функцией commit(), а
отмена — rollback().
Поддерживает ли база данных транзакции можно проверить
функцией hasFeature.
Технология ООП
Уровень пользовательского интерфейса
Представляет собой модели для отображения результата
запросов: QSqlQueryModel, QSqlTableModel,
QSqtRelationTableModel.
Технология ООП
Концепция модель-представление
Концепция модель-представление позволяет предоставлять
данные многократно без дублирования.
Возможность быстро адаптировать изменения под новую
модель хранения данных
Удобство тестирования, позволяющие использовать разные
тесты для любой модели реализующей заданный интерфейс.
Технология ООП
Концепция модель-представление
Модель — отвечает за управление данными и предоставляет
интерфейс для их чтения и записи.
Представление — представление данных пользователю и их
расположение.
Делегат — отвечает за рисование и редактирование каждого
элемента.
Возможность быстро адаптировать изменения под новую
модель хранения данных
Удобство тестирования, позволяющие использовать разные
тесты для любой модели реализующей заданный интерфейс.
Технология ООП
Архитектура модель-представление
Технология ООП
Архитектура модель-представление
Технология ООП
Архитектура модель-представление
Технология ООП
Уровень пользовательского интерфейса
Пример использование модели для осуществления выборки
данных:
QSqlTableModel model ;
model . s e t T a b l e ( "cd" ) ;
model . s e t F i l t e r ( " year ␣>=␣1998" ) ;
model . s e l e c t ( )
Аналогично запросу:
s e l e c t ∗ from cd where y e a r >= 1 9 9 8 ;
Технология ООП
Уровень пользовательского интерфейса
Для просмотра результатов результирующей выборки
используется функция record().
f o r ( i n t i = 0 ; i < model . rowCount ( ) ; i ++)
{
QSqlRecord r e c o r d = model . r e c o r d ( i ) ;
QString t i t l e = record . value (" t i t l e ") . t o S t r i n g () ;
i n t y e a r = r e c o r d . v a l u e ( " year " ) . t o I n t ( ) ;
qDebug << t i t l e << "␣" << y e a r ;
}
QSqlRecord::value() может принимать имя поля, либо его
индекс.
Технология ООП
Уровень пользовательского интерфейса
Вставка данных в модель:
QSqlTableModel model ;
model . s e t T a b l e ( "cd" ) ;
model . i n s e r t R o w s ( 0 , 1 ) ;
model . s e t D a t a ( model . i n d e x ( 0 , 0) , 113) ;
model . s e t D a t a ( model . i n d e x ( 0 , 1) , "Test" ) ;
model . s e t D a t a ( model . i n d e x ( 0 , 2) , 224) ;
model . s e t D a t a ( model . i n d e x ( 0 , 3) , 2004) ;
model . s u b m i t A l l ( ) ;
Для вставки используется функция insertRow(), для вставки
пустой строки и функция setData() — для задания значений
столбцов, принимает в качестве параметров указатель на
ячейку (QModelIndex).
После вызова submitAll() добавленная запись может быть
перемещена в другую позицию, в зависимости от
упорядоченности таблицы. А также для записи изменений в
базу данных.
Технология ООП
Уровень пользовательского интерфейса
Обновление данных:
QSqlTableModel model ;
model . s e t T a b l e ( "cd" ) ;
model . s e t F i l t e r ( " i d ␣=␣12" ) ;
model . s e l e c t ( ) ;
i f ( model . rowCount ( ) == 1 )
{
QSqlRecord r e c o r d = model . r e c o r d ( 0 ) ;
r e c o r d . s e t V a l u e ( " t i t l e " , "Test" ) ;
r e c o r d . s e t V a l u e ( " year " , r e c o r d . v a l u e ( " year " ) . t o I n t
( ) + 1) ;
model . s e t R e c o r d ( 0 , r e c o r d ) ;
model . s u b m i t A l l ( ) ;
}
Технология ООП
Уровень пользовательского интерфейса
Удаление данных:
QSqlTableModel model ;
model . s e t T a b l e ( "cd" ) ;
model . s e t F i l t e r ( " i d ␣=␣12" ) ;
model . s e l e c t ( ) ;
i f ( model . rowCount ( ) == 1 )
{
model . removeRows ( 0 , 1 ) ;
model . s u b m i t A l l ( ) ;
}
В removeRows() указывается номер строки с которой
произвести удаление и число удаляемых строк.
Технология ООП
Уровень пользовательского интерфейса
Просмотр модели и ее связь с отображением для пользователя.
Для связи модели с отображеним используются представления
QTableView и функция setModel.
model−>s e t H e a d e r D a t a ( 0 , Qt : : H o r i z o n t a l , "Name" ) ;
QTableView ∗ v i e w = new QTableView ;
view −>s e t M o d e l ( model ) ;
view −>s e t C o l u m n H i d d e n ( 0 , t r u e ) ;
view −>r e s i z e C o l u m n s T o C o n t e n t s ( ) ;
view −>s e t E d i t T r i g g e r s ( A b s t r a c t I t e m V i e w : :
AllEditTriggers )
Технология ООП