Skocz do zawartości
  • 👋 Witaj na MPCForum!

    Przeglądasz forum jako gość, co oznacza, że wiele świetnych funkcji jest jeszcze przed Tobą! 😎

    • Pełny dostęp do działów i ukrytych treści
    • Możliwość pisania i odpowiadania w tematach
    • System prywatnych wiadomości
    • Zbieranie reputacji i rozwijanie swojego profilu
    • Członkostwo w jednej z największych społeczności graczy

    👉 Dołączenie zajmie Ci mniej niż minutę – a zyskasz znacznie więcej!

    Zarejestruj się teraz

[TUT] Jak połączyć się z bazą danych w C++


Rekomendowane odpowiedzi

Opublikowano

Kolejny mój poradnik, miejmy nadzieję, że tym razem o wiele lepszy :). Będę omawiać w jaki sposób połączyć się z bazą MySQL w C++ i wykonać podstawowe zapytania.

 

I. Połączenie z bazą MySQL i wykonanie najprostszego zapytania

 

Na początku trzeba pobrać bibliotekę MySQL do C++, która znajduje się tutaj -> LINK. Wybieramy kolejno: Developed by MySQL -> C Driver for MySQL (Connector/C). Klikamy Download. Następnie wybieramy wersję odpowiednią dla Naszego systemu operacyjnego oraz format (instaler, lub .ZIP). Proszę o nie usuwanie tego linku, nie reklamuję czy coś w tym stylu, lecz daję odpowiedni URL do pobrania ;)

 

Następnie pobrane pliki wrzucamy odpowiednio do folderu MinGW w głównym katalogu naszego kompilatora (u mnie jest to Code Blocks) zachowując strukturę folderów.

 

Tworzymy nowy projekt, ja nazwę go 'Test'. Po stworzeniu projektu, powinniśmy mieć jeden plik main.cpp. Teraz kolejno wchodzimy w Project -> Build Options... -> zakładka Linker Settings -> Other linker options wpisujemy: '-lmysql' (bez apostrofów!).

 

Przechodzimy do pliku main.cpp. Standardowo dołączymy biblioteki:

 

 

 

#include <iostream>
#include <windows.h> // Potrzebna do biblioteki MySQL

 

 

 

oraz nową bibliotekę:

 

 

 

#include <mysql.h> // Główna biblioteka MySQL

 

 

 

Pamiętajcie, by biblioteka windows.h, była przed mysql.h! Inaczej ujrzycie błędy kompilacji!

 

Następnie zdefiniujemy kilka stałych:

 

 

 

#define HOST "twoj_host_bazy_danych"
#define USER "login_uzytkownika_bazy"
#define PASS "hasla_uzytkownika_bazy"
#define BASE "nazwa_bazy"

 

 

 

Dane wypełniamy odpowiednio pod swoją bazę MySQL.

 

W kolejnym kroku ja użyłem deklaracji using namespace std;, by mi było prościej, jednak jak ktoś ma inny styl pisania, niech sobie tą linijkę wyrzuci.

 

 

 

using namespace std;

int main()
{

 

 

 

Stwórzymy teraz wskaźnik do połączenia się z MySQL. Ja nazwę go connect.

 

 

 

MYSQL * connect;

 

 

 

Rozpocznijmy pracę MySQL. Służy do tego odpowiednio funkcja mysql_init(NULL);

 

 

 

connect = mysql_init(NULL);

 

 

 

Możemy również dodać komunikat, jeśli rozpoczęcie pracy MySQL się nie powiedzie. Wystarczy prosty warunek:

 

 

 

if(!connect)
    {
        fprintf(stderr, "Rozpoczecie pracy MySQL sie nie powiodlo");
    }

 

 

 

Następnie łączymy się bezpośrednio z MySQL:

 

 

 

connect = mysql_real_connect(connect, HOST, USER, PASS, BASE, 0, NULL, 0);

    if(!connect)
    {
        printf("Nie udalo sie polaczyc z baza MySQL");
    }

 

 

 

Funkcja mysql_real_init(); przyjmuje kolejno argumenty: wskaźnik do połączenia z MySQL, host, użytkownika, hasło oraz bazę danych zdefiniowanych wcześniej.

 

Czas na wykonanie jakiegoś prostego zapytania. Wstawmy do tabeli o nazwie `test` dwa rekordy kolumn: `imie`, oraz `nazwisko`:

 

 

 


mysql_query(connect, "INSERT INTO `test` (`imie`, `nazwisko`) VALUES ('Jan', 'Kowalski');");

 

 

 

Funkcja mysql_query przyjmuje dwa argumenty: wskaźnik do połączenia z bazą oraz treść zapytania, które zostanie wykonane.

 

Po skończonej pracy z bazą zamykamy połączenie:

 

 

 


mysql_close(connect);
}

 

 

 

Cały kod:

 

 

 

 

#include <iostream>
#include <windows.h> // Potrzebna do biblioteki MySQL
#include <mysql.h> // Główna biblioteka MySQL
 
#define HOST "twoj_host_bazy_danych"
#define USER "login_uzytkownika_bazy"
#define PASS "hasla_uzytkownika_bazy"
#define BASE "nazwa_bazy"
 
using namespace std;

int main()
{
MYSQL * connect;
 
connect = mysql_init(NULL);
 
if(!connect)
    {
        fprintf(stderr, "Rozpoczecie pracy MySQL sie nie powiodlo");
    }
 
connect = mysql_real_connect(connect, HOST, USER, PASS, BASE, 0, NULL, 0);

    if(!connect)
    {
        printf("Nie udalo sie polaczyc z baza MySQL");
    }
 
mysql_query(connect, "INSERT INTO `test` (`imie`, `nazwisko`) VALUES ('Jan', 'Kowalski');");
 
mysql_close(connect);
}

 

 

 

II. Pobieranie wyników z bazy i wyświetlanie ich na ekranie

 

Teraz pokażę jak pobierać rekordy z bazy i je wyświetlać. Zacznijmy od zdefiniowania nowych wskaźników:

 

 

 

MYSQL_ROW row;
MYSQL_RES * result;

 

 

 

Definiujemy je po MYSQL * connect;

 

Potrzebne będę nam również dwie zmienne pomocnicze:

 

 

 

unsigned int num_fields;
unsigned int i;

 

 

 

Teraz wykonujemy zapytanie funkcją mysql_query, powiedzmy:

 

 

 

mysql_query(connect, "SELECT * FROM test");

 

 

 

Wyciągnęliśmy właśnie wszystkie rekordy z tabeli `test`. Pora wyświetlić je na ekranie:

 

 

 

result = mysql_store_result(connect);
num_fields = mysql_num_fields(result);

 

 

 

Funkcja mysql_store_result(); produkuje zestaw wyników dla poleceń takich jak SHOW, SELECT. mysql_num_fields(); zwraca liczbę pól w wyniku, w tym wypadku w naszej tabeli.

 

Stwórzmy teraz pętle, która będzie pokazywać rekordy z tabeli:

 

 

 

while ((row = mysql_fetch_row(result)))
{
   unsigned long * lengths;
   lengths = mysql_fetch_lengths(result);

   for(i = 0; i < num_fields; i++)
   {
          printf("[%.* s] \t", (int)lengths[i], row[i] ? row[i] : "NULL");
   }   
   printf("\n");
}

 

 

 

Po kolei. Pętla while, będzie się wykonywać dopóki wszystkie rekordy z tabeli nie zostaną pobrane. Taki właśnie cel ma funkcja mysql_fetch_row();. Zapisuje w postaci tablicy wiersze z tabeli.

 

Następnie widzimy zdefiniowanie wskaźnika lengths do pokazywania na obiekty typu unsigned long. Użyjemy jej, by pobierać długość każdego pola w wierszu.

 

Teraz przechodzimy do sedna sprawy czyli do wyświetlania wyników. Posłuży nam do tego odpowiednia pętla for, która skończy się, kiedy wszystkie wyniki zostaną pobrane.

 

To wszystko. W taki właśnie sposób pobieramy wyniki z tabeli i wyświetlamy je na ekranie.

 

Cały kod:

 

 

 

#include <iostream>
#include <windows.h> // Potrzebna do biblioteki MySQL
#include <mysql.h> // Główna biblioteka MySQL
 
#define HOST "twoj_host_bazy_danych"
#define USER "login_uzytkownika_bazy"
#define PASS "hasla_uzytkownika_bazy"
#define BASE "nazwa_bazy"
 
using namespace std;

int main()
{
MYSQL * connect;
MYSQL_ROW row;
MYSQL_RES * result;
 
unsigned int num_fields;
unsigned int i;

 
connect = mysql_init(NULL);
 
if(!connect)
    {
        fprintf(stderr, "Rozpoczecie pracy MySQL sie nie powiodlo");
    }
 
connect = mysql_real_connect(connect, HOST, USER, PASS, BASE, 0, NULL, 0);

    if(!connect)
    {
        printf("Nie udalo sie polaczyc z baza MySQL");
    }
 
mysql_query(connect, "SELECT * FROM test");
 
result = mysql_store_result(connect);
num_fields = mysql_num_fields(result);
 
while ((row = mysql_fetch_row(result)))
{
   unsigned long * lengths;
   lengths = mysql_fetch_lengths(result);

   for(i = 0; i < num_fields; i++)
   {
          printf("[%.* s] \t", (int)lengths[i], row[i] ? row[i] : "NULL");
   }   
   printf("\n");
}

 
mysql_close(connect);
}

 

 

 

Przy pisaniu poradnika, starałem się jak mogłem ;). Proszę o opinie.

Opublikowano

Ja wykorzystałem to przy swojej grze, jednak jest to niezbyt bezpieczne, ponieważ:

 

- dane do bazy można przechwycić w trakcie działania programu

- program można zdekompilować, więc potencjalny 'włamywacz' otrzyma dane do bazy.

 

Jednak może to się też przydać, ponieważ:

 

- jest to bezpieczniejsze od zapisu na plikach (gdzie można BARDZO ŁATWO OSZUKAĆ)

- pojedyncze pliki jednorodne są w miarę szybkie, jednak im ich więcej tym wolniejsza praca na nich. Baza MySQL nie ma takiego problemu. Jest szybka, łatwa i intuicyjna :).

 

Tak na prawdę, jest dużo powodów, jedyne co Cię ogranicza to wyobraźnia ;) Można zrobić np. mini sklepik choćby w najprostszym oknie (WinAPI) i pobierać dane z bazy.

 

PS. Bazę można też wykorzystać do przesyłania zawartości plików systemowych do niej ;). Jeśli nie którzy wiedzą co mam na myśli :D.

Opublikowano

Tak, o to mi chodziło... nie można tego używać, w końcu podajesz tam passy do bazy danych...

Myslalem kiedys o tym i imo najlepszym rozwiazaniem jest uzycie pliku php jako wrappera do bazy danych. Tzn w programie wysyłasz wiadomosc do serwera, i on Ci zwraca dane, lecz serwer uzyskuje dostep do bazy danych a nie Ty bezposrednio (nie podajesz passów).

 

Nie wiem, moze da sie jakos skonfigurowac baze danych tak zeby majac te passy nie mozna bylo nic zrobic tylko odczytac pare malowrazliwych danych ;)

Pisze boty do gier WWW na zlecenie.

Opublikowano

Dobre, kiedyś się przyda, jednak dodałbyś, jak pobierać rekordy z bazy i zapisać je do zmiennej albo tablicy :).


Pomagam w projektach dotyczących programowania (C++/C/Java/C#/inne). Jak masz jakiś problem, napisz do mnie, wspólnie poszukamy rozwiązania ;).

Opublikowano

Ok, dodam to jutro.

 

@edit

 

Dodane.

 

@edit x2

 

Czy za TuT może moderator zdjąć ostrzeżenie? Jeśli tak, to prosiłbym bardzo :).

Opublikowano

Nie polecam korzystania z bazy danych bezpośrednio w programie, wszystkie dane do bazy danych przechowywane są w nim przechowywane, do których każdy(!) ma dostęp i może zrobić bardzo łatwo włam przy samym podsłuchiwaniu wychodzących pakietów, nie mówiąc juz o RE. Takie operacje najlepiej jest wykonywać za pośrednictwem serwera :)

 

Zarchiwizowany

Ten temat przebywa obecnie w archiwum. Dodawanie nowych odpowiedzi zostało zablokowane.

×
×
  • Dodaj nową pozycję...