Atom

2010
28
maj

Kurs Qt – część 9 – SQL

Kategoria: Kurs Qt, Programowanie, QtMatthew @ 21:48

I przyszedł czas na kolejną część kursu Qt. Dzisiaj o wykorzystaniu baz danych w swoich aplikacjach. Pokażę jak ustanawiać połączenie z bazą danych, wykonać na niej zapytania oraz kilka przydatnych sztuczek związanych z operowaniem na bazach. Miłego czytania!

Odmiennie niż zwykle, nie stworzymy aplikacji okienkowej, ale posłużymy się prostą, konsolową, która wygląda tak:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QDebug>
#include <QString>

int main(int argc, char *argv[])
{
   QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");

   db.setHostName("localhost");
   db.setDatabaseName("qt");
   db.setUserName("login");
   db.setPassword("haslo");

   if (!db.open())
   {
      qDebug() << "Błąd: nie można się połączyć z bazą!";
   }
   else
   {
      qDebug() << "Nawiązano połączenie z bazą danych.";

      QSqlQuery dodawanie;
      dodawanie.exec("INSERT INTO test (imie, nazwisko, wiek) VALUES ('Stefan', 'Kowalski', '20')");
      dodawanie.exec("INSERT INTO test (imie, nazwisko, wiek) VALUES ('Jan', 'Nowak', '36')");

      QSqlQuery pobieranie;
      pobieranie.exec("SELECT * FROM test");

      while (pobieranie.next())
      {
         QString imie = pobieranie.value(1).toString();
         QString nazwisko = pobieranie.value(2).toString();
         int wiek = pobieranie.value(3).toInt();
         qDebug() << imie << nazwisko << wiek;
      }
   }

   return 0;
}

W linii 8. dodajemy połączenie do bazy SQL, wybierając rodzaj sterownika, który odpowiada bazie, której chcemy użyć. Istnieje możliwość nadania nazwy dla naszego połączenia, dzięki czemu, możemy mieć wiele połączeń do tej samej bazy danych. Qt posiada mechanizm domyślnego połączenia (w przypadku gdy mamy ich więcej). Powoduje on, że jeżeli przy wywołaniu zapytania nie określimy bazy na której chcemy je wykonać, zostanie one wykonane na domyślnej bazie.

W liniach od 10. do 13. określamy parametry połączenia z bazą, jak adres, nazwa, login oraz hasło. W linii 15 sprawdzamy czy zostało otworzone połączenie aplikacji z bazą. Jeżeli wystąpił błąd, aplikacja o tym informuje i jest zamykana. W liniach od 23. do 25. dodajemy dwa rekordy do bazy, przy pomocy obiektu klasy QSqlQuery. Gdy dane zostaną dodane, tworzymy obiekt, którego celem będzie odczytywanie danych z bazy i uruchamiamy na nim zapytanie. Bardzo ważne: nie powinno się używać * (zrobiłem to z lenistwa). Najlepiej konkretnie wskazywać kolumny które chcemy pobrać. Wiąże się to z tym, że w przypadku dania *, kolejność kolumn jest niezdefiniowana i próba odczytania ich przy pomocy metody value() może przynieść inne rezultaty niż oczekiwaliśmy.

Sama metoda value() zwraca dane pobrane z bazy umieszczone w obiekcie klasy QVariant. Jako argument przyjmuje indeks kolumny którą chcieliśmy pobrać (liczone od zera).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
QSqlDatabase::database().transaction();
QSqlQuery query;

query.exec("SELECT id FROM employee WHERE name = 'Torild Halvorsen'");

if (query.next())
{
   int employeeId = query.value(0).toInt();
   query.exec("INSERT INTO project (id, name, ownerid) "
      "VALUES (201, 'Manhattan Project', "
      + QString::number(employeeId) + ')');
}

QSqlDatabase::database().commit();

Powyższy przykład pokazuje jak wykorzystać mechanizm transakcji w bazie danych (jeżeli jest dostępny). Różnica w stosunku do normalnych zapytań jest taka, że fragment, który powinien być poddany transakcji zaczynamy od QSqlDatabase::database().transaction(); (czym informujemy o zaczęciu transakcji) a kończymy poprzez QSqlDatabase::database().commit();.

To czy baza udostępnia nam pewne mechanizmy, możemy sprawdzić wywołując metodę QSqlDriver::hasFeature(), jako parametr podając jedną z wartości enuma QSqlDriver::DriverFeature.

Z bazami to na razie tyle. Za jakiś czas pewnie wrócę do tego tematu. Jak zwykle repozytorium gita z kodem użytym w tej części kursu można pobrać stąd. Do następnego!

18 komentarzy do “Kurs Qt – część 9 – SQL”

  1. lukiasz, dnia 23 lipca 2010 o 19:35 napisał(a):

    Dobra robota! Czekam na następny odcinek kursu :)

  2. Wolv, dnia 30 lipca 2010 o 15:32 napisał(a):

    Krótko, zwięźle i na temat. Czekam na kolejne części kursu ; )
    Masz zamiar pisać coś więcej na temat OpenGL?

  3. Matthew, dnia 30 lipca 2010 o 16:52 napisał(a):

    @Wolv: jeżeli bardziej poznam OpenGL (na co w najbliższym czasie się nie zapowiada, chyba że bardzo się zmotywuję do pisania własnego cRPG ;D) to pewnie rozszerzę. W planach mam dopisanie jeszcze coś o WebKitcie a dalej rozszerzenie i poprawienie już istniejących części kursu. Co potem to się zobaczy.

  4. Wolv, dnia 30 lipca 2010 o 19:24 napisał(a):

    W takim razie czekam na jakąś ciekawą notkę o WebKitcie.
    BTW: Pozwoliłem sobie na podlinkowanie do Twojego kursu Qt ;)

  5. Matthew, dnia 30 lipca 2010 o 19:51 napisał(a):

    @Wolv: po chrześcijańsku wybaczam. ;P

  6. dmx, dnia 14 września 2010 o 11:23 napisał(a):

    witam,mam pytanie,czy znasz jakis dobry kurs sql online? Dzieki:) p.s. Wiem ze troche nie na temat,ale moglby sie pojawic tutorial o zapisywaniu/odczytywaniu plikow,sam to wlasnie przerabiam w dokumentacji i widze ze moznaby pozyteczny tutorial z tego zrobic:)

  7. yavin, dnia 2 grudnia 2010 o 21:30 napisał(a):

    Fajny kurs, a może wiesz szanowny autorze jak się dobrać do Firebirda?

  8. Drraven, dnia 1 stycznia 2011 o 20:14 napisał(a):

    U mnie wywala błąd ze nie może znaleźć qsqldatabase (nie mam tego nawet – sprawdzałem). Ale imho powinno być bo qt instalowałem na początku grudnia. I co mam robić szukać w necie tego pliku czy instalować qt sdk od nowa ?

  9. Pomoc, dnia 7 stycznia 2011 o 17:59 napisał(a):

    @Drraven: dodaj linię QT += sql w pliku .pro

  10. Drraven, dnia 7 stycznia 2011 o 20:30 napisał(a):

    dzięki.

  11. Karol, dnia 4 kwietnia 2011 o 15:57 napisał(a):

    Mi wywala w momencie używania „QString”: ” Invalid use of incomplete type ‘struct QVaraint’ „.

  12. stefan87, dnia 16 kwietnia 2011 o 11:33 napisał(a):

    zeby dodac cos do bazy test trzeba ja sobie najpierw utworzyc za pomoca jakiegos innego programu tak?
    dodawanie.exec(„INSERT INTO test (imie, nazwisko, wiek) VALUES (‘Stefan’, ‘Kowalski’, ’20′)”); -> tutaj jest utworzona jakas baza danych o nazwie test?? da sie tworzyc takie bazy w qt bez odpalania innych programow?
    QSqlDatabase db = QSqlDatabase::addDatabase(„QMYSQL”); -> sluzy tylko do nawiazania polaczenia z jakas baza??

    Sory jezeli cos zamotalem, ale caly kod mi sie skompilowal ale nie sa obslugiwane te zapytania bo nie wyswietla mi sie ten qDebug() << imie << nazwisko << wiek;

  13. GwynBleidD, dnia 30 kwietnia 2011 o 14:31 napisał(a):

    Pierwsze co powinno się ukazać w tym tutorialu, to mocno wytłuszczona notka o tym, że qt po instalacji nie posiada pluginu MySQL! Trzeba go sobie ręcznie skompilować. Najlepiej użyć do tego wersji mysql-essential-5.1.56-win32, nawet na komputerach 64 bitowych (z 64 bitową wersją mysql plugin się nie skompiluje). Krótki poradnik dla systemów Windows:

    1. Ściągamy instalator serwera mysql (wersja essential-5.1.56-win32 jako jedyna mi się skompilowała)
    2. Instalujemy serwer mysql najlepiej do katalogu c:\MySQL (spacje w ścieżce powodują, że mamy więcej roboty do wykonania, lepiej ich unikać), przy instalacji zaznaczamy wszystkie komponenty
    3. Wchodzimy do katalogu w którym zainstalowaliśmy serwer SQL a w nim w lib\opt (jeśli nie ma katalogu opt to się nie martwimy, wszystko będzie w katalogu lib) i kopiujemy plik libmysql.lib
    4. Wklejamy libmysql.lib do katalogu %Qtdir%\src\plugins\sqldrivers\mysql (przez %Qtdir% rozumiem katalog binarek QT, czyli domyślnie C:\Qt\wersja.Qt\qt)
    5. Pobieramy Mingw-utils 0.3 i instalujemy do mingw z QT (domyślnie C:\Qt\Wersja.Qt\mingw)
    6. Odpalamy Qt Command Prompt (Start->Programy->Qt SDK-> Qt Command Prompt)
    7. Przechodzimy do katalogu src\plugins\sqldrivers\mysql i wykonujemy kolejno polecenia:

    1
    2
    3
    4
    reimp -d libmysql.lib
    dlltool -k --input-def LIBMYSQL.def --dllname libmysql.dll --output-lib libmysql.a
    qmake "INCLUDEPATH+=C:/MySQL/include" "LIBS+= -L./" mysql.pro
    -k --input-def LIBMYSQL.def --dllname libmysql.dll --output-lib libmysql.a

    8. Kopiujemy z libs\opt z katalogu instalacji mysql plik libmysql.dll i wklejamy go do %qtdir%\bin. Jeśli nie możemy znaleźć pliku libmysql.dll to możemy go pobrać z tej paczki: http://www.devqt.pl/mysql.zip (kopiujemy tylko plik libmysql.dll!)
    9. Dla próby kompilujemy w qt creatorze program o następującym źródle:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    QCoreApplication a(argc, argv);
     
    QSqlDatabase base;
    QStringList list;
    QTextStream cout(stdout);
    list=base.drivers();

    cout<<list<<endl;
    QTimer::singleShot(5000, &a, SLOT(quit()));
    return a.exec();
  14. Matthew, dnia 3 maja 2011 o 17:35 napisał(a):

    @GwynBleidD: pozwolisz że to ja będę decydował co powinno się ukazać w tutorialu a co nie? Bo widzisz, to co dałeś to przykład tego jak to zrobić na windowsie co mnie specjalnie nie interesuje (wszystko i tak robię pod linuksem).

  15. slaver, dnia 7 maja 2011 o 19:04 napisał(a):

    Chyba autor zapomniał w kodzie na początku dodać: #include , bo bez tego kompilator wypluwa: „invalid use of incomplete type ‘struct QVariant’” – a początkujących programistów jak ja może to zbić z tropu.
    Może warto było dodać na początku jakąś notkę że obsługa MySQLa w QT wymaga samemu skompilowania drivera? Nie wiem jak sprawa tego drivera wygląda pod linuksem, ale Qt to fajne multiplatformowe api i równie dobrze programuje mi się w nim pod windą.

  16. slaver, dnia 7 maja 2011 o 19:06 napisał(a):

    sorry, powinno być #include „QVariant”, w tych ostrych nawiasach, ale mi je wcieło.

  17. Karol, dnia 21 maja 2011 o 17:32 napisał(a):

    @GwynBleidD: Próbowałem postępować za Twoimi wskazówkami, ale albo coś źle zrozumiałem, albo jest błąd. dochodzę do punktu 7. Jeśli dobrze zrozumiałem są to trzy polecenia. Pierwsze reimp, drugie dltool, trzecie qmake. Czy czwarta linijka należy też do qmake?

  18. GwynBleidD, dnia 13 czerwca 2011 o 13:05 napisał(a):

    Ostatnia linia powinna wyglądać tak:
    [code]mingw32-make[/code]

    @Matthew: mógłbyś to poprawić?

Zostaw komentarz

Subscribe without commenting