Lekce 2 - Databáze v C++ a Qt - Připojení k databázi a nová tabulka
V minulé lekci, Úvod do databází v C++ a Qt, jsme se uvedli do problematiky databází v C++.
Než se pustíme do něčeho okenního, seznámíme se se základními principy SQL v Qt v konzolovém prostředí. Postupně si v tutoriálu ukážeme, jak zjistíme, zda vůbec máme k dispozici ovladač pro zvolený databázový stroj a jak se pomocí něj k databázi připojíme. Dále postoupíme k vytvoření databáze a tabulky v ní.
První databázový projekt v C++
Založíme si konzolový projekt v Qt Creator, jak si jej nazvete je jen na vás. Pokud jste si neprošli kurz o Qt, tak jak stvořit nový projekt v Creatoru shrnu do několika obrázků:

Poté dostanete dialog s výběrem typu aplikace:

Následně si můžete zvolit umístění projektu.
project.pro
První, co budeme muset pro zprovoznění databáze udělat, je otevřít si
projektový soubor *.pro
, který najdete přímo v Creatoru:

Najdete v něm něco takového:
QT -= gui CONFIG += c++11 console CONFIG -= app_bundle ...
Bohužel Qt neví, že chceme používat SQL a musíme mu to říci. Přidáme tedy jeden řádek:
QT -= gui QT += sql ...
main.cpp
Nyní přejdeme do výchozího souboru, který si osekáme do naprosto základního tvaru:
#include <QCoreApplication> #include <QDebug> #include <QSqlDatabase> #include <QSqlDriver> #include <QSqlError> #include <QSqlQuery> int main(int argc, char *argv[]) { Q_UNUSED(argc); Q_UNUSED(argv); }
Máme zde několik nových importů, pojďme si je popsat:
<QDebug>
- Tato knihovna nám usnadní výstup na konzoli. Nebudeme používat standardníQTextOut
,ale ladící informace.
<QSqlDatabase>
- Třída pro připojení a vytvoření databáze.<QSqlDriver>
- Abstraktní třída ovladačů - umožní přístup ke specifické databázi.<QSqlError>
- Třída chybových výstupů v SQL databázi.<QSqlQuery>
- Třída pro SQL dotazy.
Dále jsme použili makro Q_UNUSED()
, čímž označíme, že
argumenty aplikace nebudeme využívat. Zatím nic složitého.
Konstanta s názvem ovladače
Tímto máme připravenou hlavní funkci pro experimenty s databází. Jako první věc si přidáme konstantu s názvem ovladače pro databázi SQLite :
//... const QString DRIVER = "QSQLITE"; //...
Připojení k databázi
Následně se zkusíme připojit k databázi a zároveň otestovat několik chybových stavů. Databázi si vytvoříme zatím pouze v paměti, abychom se při experimentování nezatěžovali se soubory. Kód bude následující:
// ... QSqlDatabase db; if (QSqlDatabase::isDriverAvailable(DRIVER)) { db = QSqlDatabase::addDatabase(DRIVER); db.setDatabaseName(":memory:"); qDebug() << "SQLite is ok"; // Sem budeme vkládat další kód... } else { qFatal("SQLite driver not available"); } // ...
Na začátku vytváříme instanci databáze. Pokud je driver k dispozici, budeme pokračovat. Pokud nemáme ovladač, je zbytečné pokračovat a ukončíme program s touto informací.
Uvnitř podmínky používáme statickou metodu, která přidá ovladač k
SQLite databázi. Dále nastavíme jméno databáze. Nyní nám bude databáze
stačit v paměti. Nezapomeňte i dvojtečky. Pokud byste chtěli vytvořit
souborovou databázi, uvedete název souboru, např.: data.db
. To
si ale ukážeme dále v kurzu.
Všimněte si, že funkce qDebug()
používá normální
výstupní proud, ovšem můžete použít i formátový řetězec jako argument
funkce.
Dostaneme následující výstup:
Konzolová aplikace
SQLite is ok
Zavřete toto okno stisknutím tlačítka <RETURN>...
Nyní můžeme databázi otevřít. Když se to nepovede, opět nemá význam pokračovat a program ukončíme. Pokračujeme samozřejmě ve větvi programu v podmínce:
//... // Otevíráme databázi if (db.open()) { qDebug("Databázi se zdařilo otevřít"); } else { qWarning() << "ERROR: " << db.lastError().text(); return 1; } //...
Výstup:
Konzolová aplikace
SQLite is ok
Databázi se zdařilo otevřít
Záměrně jsem nepoužil funkci qFatal(char *)
, protože se mi
nechtělo vytvářet formátový řetězec a ještě převádět na ASCII kód.
qWarning()
používá výstupní proud a snadněji pracuje s textem
typu QString
. Program v případě chyby jednoduše ukončíme
příkazem return 1;
Za povšimnutí určitě stojí funkce db.lastError().text()
,
která skutečně vrací textovou reprezentaci poslední chyby, která
nastala.
Vytvoření databázové tabulky
Dalším krokem v databázi vytvoříme nějakou jednoduchou tabulku. Např. seznam lidí s jejich ID a jménem:
QSqlQuery query("CREATE TABLE people (id INTEGER PRIMARY KEY, name TEXT)");
CREATE TABLE
Pro vytvoření nové tabulky používáme SQL příkaz
CREATE TABLE
následovaný názvem tabulky, v našem případě
people
, a dále závorkou. V té uvádíme jaké má tabulka
sloupce jako název sloupce a jeho datový typ. Jednotlivé sloupce oddělujeme
čárkou. Typ INTEGER
označuje celá čísla a TEXT
text. PRIMARY KEY
u sloupce id
udává, že se jedná
o unikátní identifikátor záznamů. Toto id
se bude také
automaticky navyšovat s každou nově vloženou osobou.
QSqlQuery
Vytvořili jsme instanci QSqlQuery
. Na
tomto je pozoruhodné, že příkaz v argumentu se okamžitě vykoná, aniž
bychom museli volat query.exec()
. Je to sice příjemná vlastnost,
ale přeci jen bychom možná rádi věděli, zda operace proběhla úspěšně.
Qt myslí i na toto a dalo k dispozici funkci
bool query.isActive()
, která vrací true
při
úspěchu. Můžeme ji tedy rovnou aplikovat:
//... if (query.isActive()) { qDebug() << "Tabulka vytvořena"; } else { qWarning() << "ERROR: " << query.lastError().text(); return 1; } //...
Výstup našeho programu je nyní následující:
Konzolová aplikace
SQLite is ok
Databázi se zdařilo otevřít
Tabulka vytvořena
Zde by opět v případě chyby v programu nemělo smysl pokračovat, protože když tabulka není, nelze do ní nic uložit.
Tabulku máme připravenou a data si do ní vložíme zas příště, v lekci Databáze v C++ a Qt - Základy Qt SQL.