Tym razem chciałem przedstawić konfigurację i obsługę lokalnej bazy danych z wykorzystaniem biblioteki SQLite.
Zakładam, że już znasz podstawy programowania w C# i obsługę programu Visual Studio 2015 - więc możliwe, że początkującego to nie zainteresuje, ale różnie to jest.
Więc przystępujemy do działania.
Przed przystąpieniem do pisania programu, należy najpierw zaimportować i dodać potrzebne biblioteki. Można to zrobić na wiele sposobów. Jednym z nich jest ściągnięcie odpowiednich plików ze strony źródłowej SQLite. Tylko, którą wersję wybrać i jakie pliki? Jest też duże prawdopodobieństwo, że braknie biblioteki SQLite.Interop.dll. Ja natomiast pokażę inny sposób, który w łatwy sposób doda wszystkie potrzebne pliki - poprzez program Visual dzięki pakietom NuGet. Aby tego dokonać należy w eksploratorze projektu kliknąć prawym przyciskiem myszy na odwołania (references) i z menu wybrać "Zarządzaj pakietami NuGet...".
Otworzy nam się nowe okienko w którym mamy możliwość wyboru odpowiedniego pakietu. W tym celu przechodzimy do zakładki Przeglądaj i w polu wyszukiwania wpisujemy SQLite. Po wyszukaniu i wyświetlenie wyników wybieramy pakiet System.Data.SQLite. Po prawej stronie w informacjach dotyczących pakietu naciskami przycisk Zainstaluj, oraz potwierdzamy OK w kolejnym okienku. Wszystkie wymagane składniki pakietu zostaną automatycznie zainstalowane.
Należy jeszcze sprawdzić czy kopia lokalna jest tworzona. Przechodzimy do kategorii odwołania w naszym projekcie i rozwijamy je. Znajdować się tam będą między innym odwołania takie jak System.Data.SQLite, System.Data.SQLite.EF6, System.Data.SQLite.Linq. Po zaznaczeniu odpowiedniego odwołania (oczywiście dotyczącego tylko SQLite) w okienku właściwości (Properties) przy opcji kopia lokalna (Copy Local) powinno być ustawione True, jak to pokazano na poniższym zdjęciu:
Dzięki temu ustawieniu w folderze w którym znajduje się nasz plik wykonywalny exe naszego programu zostaną utworzone pliki które są konieczne do prawidłowego działania naszego programu.
Po konfiguracji przechodzimy do programu.
Omówię jedynie fragmenty kodu, które są potrzebne do obsługi bazy danych.
Pod tym adresem można znaleźć przydatne informacje dot. budowania składni zapytań SQL.
Nasz program będzie umożliwiał utworzenie nowej bazy danych, otwarcie istniejącej, oraz dodanie i usunięcie danych, a także wypisanie kolejnych danych, które są zawarte w bazie danych. W projekcie zostaną użyte następujące kontrolki:
- Button;
- TextBox;
- Label
Wyglądać to będzie następująco:
Opiszę jedynie kod odpowiedzialny za obsługę bazy danych. W programie znajduje się dość duża ilość komentarzy opisująca co się w danej chwili dzieje
Obsługę lokalnej bazy danych można podzielić na kilka czynności:
- Utworzenie nowego pliku
- Otwarcie/Zamknięcie bazy danych
- Wysłanie zapytania, które nie zwraca żadnych danych (np. utworzenie tabeli, dodanie nowych danych)
- Wysłanie zapytanie, które zwraca jakiś wynik (np, wyszukanie danych)
W pierwszej kolejności zarejestrujemy przestrzeń nazw naszej biblioteki:
Kod: Zaznacz cały
using System.Data.SQLite;
Aby utworzyć nowy plik naszej bazy należy wywołać funkcję:
Kod: Zaznacz cały
//tworzenie nowego pliku
SQLiteConnection.CreateFile("c:\\nowe_dane.db");
W programie, który przedstawia sposób wykorzystania bazy danych do funkcji przekazywana jest zmienna path, która zawiera lokalizację pliku. Po utworzeniu pliku konieczne jest utworzenie nowej tabeli w bazie danych, ale o tym za chwilę.
Otwarcie pliku wymaga utworzenia najpierw zmiennej, do której przypisany będzie nasz obiekt, czyli plik naszej bazy danych.
Kod: Zaznacz cały
//zmienna przechowująca obiekt bazy danych
SQLiteConnection db_connect;
//utworzenie obiektu potrzebnego do połączenia się z bazą, składnia wymagana przez bibliotekę.
db_connect = new SQLiteConnection("Data Source =" + path + ";Version=3;");
//połączenie się z bazą danych - funkcja tworząca nowy plik nie powoduje otwarcia go
db_connect.Open();
Następnie tworzymy obiekt, który przypisany jest do wcześniej utworzonej zmiennej. Jako parametr przekazywana jest składnia zawierająca adres naszego pliku, oraz wersję bazy danych. Możliwe jest również przesłanie innych informacji, takich jak np. hasło, ale na chwilę obecną nie zajmowałem się tym. Informacje na temat tej składni można znaleźć pod tym adresem- i nie tylko hasła. W ostatniej linijce poprzez wywołanie funkcji/metody Open() otwierane jest połączenie z bazą danych. Zamknięcie bazy danych wykonuje się w bardzo prosty sposób, poprzez wywołanie metody/funkcji Close().
Kod: Zaznacz cały
//zamknięcie połączenia z bazą danych
db_connect.Close();
Warto tutaj wspomnieć, że w przypadku, gdy plik pod wskazanym adresem nie istnieje, a zostanie wywołana funkcja/metoda Open(), plik ten zostanie utworzony. Jednak nie zalecane jest tworzenie w ten sposób nowych plików, z tego względu, że mogą one zawierać później błędy.
Po utworzeniu i otwarciu pliku, należy w bazie danych utworzyć nową tabelę. Przedstawię najpierw, jak wygląda składnia wysłania zapytania bez zwrotu danych.
Kod: Zaznacz cały
//zmienna przechowująca obiekt do wysyłania zapytań
SQLiteCommand db_command;
//utworzenie obiektu który odpowiada za wysyłanie zapytania
db_command = new SQLiteCommand(db_querry, db_connect);
//wykonanie/wysłanie zapytania
db_command.ExecuteNonQuery();
W pierwszej kolejności tworzona jest zmienna przechowująca obiekt odpowiedzialny za wysyłanie zapytania, a w kolejnej tworzony jest ten obiekt. Przekazywane jest do niego zapytanie (db_querry w moim przypadku jest zmienną typu string, która zawiera składnię zapytania), oraz zmienna przechowująca obiekt podłączonej bazy danych, który został utworzony przed jego otwarcie. Po utworzeniu obiektu, wykonywane jest jego zapytanie poprzez wywołanie funkcji odpowiedzialnej za przesłanie zapytania które nie zwraca odpowiedzi.
Przykład tworzenia nowego pliku wraz z utworzeniem nowej tabli przedstawia się następująco:
Kod: Zaznacz cały
public string path = null; //zmienna przechowująca lokalizację bazy danych
public SQLiteConnection db_connect; //zmienna przechowująca obiekt bazy danych
public string db_querry = null; //zmienna przechowująca zapytanie do bazy danych
public SQLiteCommand db_command; //zmienna przechowująca obiekt do wysyłania zapytań
//tworzenie nowego pliku i tutaj po tym należy utworzyć tabelę w nowej bazie
SQLiteConnection.CreateFile(path);
//utworzenie obiektu potrzebnego do połączenia się z bazą, składnia wymagana przez bibliotekę.
db_connect = new SQLiteConnection("Data Source =" + path + ";Version=3;");
//połączenie się z bazą danych - funkcja tworząca nowy plik nie powoduje otwarcia go
db_connect.Open();
//utworzenie nowego zapytania dotyczącego utworzenia nowej tabeli w bazie danych
db_querry = "CREATE TABLE 'Osoby' ( 'Imie' TEXT, 'Nazwisko' TEXT)";
//utworzenie obiektu który odpowiada za wysyłanie zapytania
db_command = new SQLiteCommand(db_querry, db_connect);
//wykonanie/wysłanie zapytania
db_command.ExecuteNonQuery();
//zamknięcie połączenia z bazą danych
db_connect.Close();
W tym przypadku tworzona jest nowa tabela która nosi nazwę "Osoby". Będzie ona zawierała kolumny "Imie" , oraz "Nazwisko" , których zawartość będzie typu TEXT.
Natomiast dodanie nowych danych do tabeli wygląda następująco:
Kod: Zaznacz cały
//utworzenie nowego zapytania dodającego nowe dane do bazy
db_querry = "INSERT INTO 'Osoby' ('Imie', 'Nazwisko') VALUES ('"+ textBox2.Text +"','" + textBox3.Text + "');";
//utworzenie obiektu który odpowiada za wysyłanie zapytania
db_command = new SQLiteCommand(db_querry, db_connect);
//wykonanie/wysłanie zapytania
db_command.ExecuteNonQuery();
Do tabeli "Osoby" do kolumny "Imie" , oraz "Nazwisko" dodane są wartości wpisane do textbox2, oraz textbox3.
Kolejna czynność jaka jest wykonywana przy korzystaniu z bazy danych, to odczyt danych z tabeli bazy danych. Aby tego dokonać, należy najpierw utworzyć nową zmienną, z której będziemy odczytywać dane z kolejnych kolumn.
Kod: Zaznacz cały
//zmienna przechowująca odebrane informacje zwrócone dla zapytania doczytująceg
SQLiteDataReader db_read;
Następnie do tej zmiennej przypisuje się rezultat jaki zwraca funkcja wysyłająca zapytanie związane z odczytem danych.
Kod: Zaznacz cały
//wykonanie zapytania odczytującego dane z bazy danych
db_read = db_command.ExecuteReader();
Tak odebrane dane z lokalnej bazy danych, są teraz gotowe aby je odczytać. Dokonuje się tego poprzez wywoływanie funkcji Read() - przed pierwszym odczytaniem danych należy również ją wywołać. Odczyt danych wykonuje się wiersz po wierszu, tzn. wywołanie funkcji Read powoduje przejście do następnego wiersza. Odczytywanie danych dokonuje się poprzez odczyt każdej komórki z osobna. Dokonuje się tego po kolei dla każdego wiersza wskazując odpowiednią kolumną:
Kod: Zaznacz cały
db_read.Read(); //przed pierwszym użyciem też należy użyć funkcji odczytującej dane z bazy
label2.Text = db_read["Imie"].ToString(); //odczytywanie dokonuje się poprzez wskazanie nazyw kolumny
label3.Text = db_read[1].ToString(); //bądź poprzez podanie numeru kolumny - liczenie od 0
Odczyt danych z odpowiedniej kolumny dokonuje się jak odczyt z tabeli 1-wymiarowej. Można wykorzystać do tego indeks kolumny (liczy się od 0) bądź nazwę kolumny w bazie danych.
Poniżej zamieszczam cały przykład umożliwiający odczytanie danych z bazy danych.
Kod: Zaznacz cały
//zmienna przechowująca odebrane informacje zwrócone dla zapytania doczytująceg
public SQLiteDataReader db_read;
//utworzenie nowego zapytania powodującego odczytanie/wyszukanie wszystkich danych z bazy
db_querry = "SELECT * FROM 'Osoby'";
//utworzenie obiektu który odpowiada za wysyłanie zapytania
db_command = new SQLiteCommand(db_querry, db_connect);
//wykonanie zapytania odczytującego dane z bazy danych
db_read = db_command.ExecuteReader();
//odczytywanie danych
db_read.Read(); //przed pierwszym użyciem też należy użyć funkcji odczytującej dane z bazy
label2.Text = db_read["Imie"].ToString(); //odczytywanie dokonuje się poprzez wskazanie nazyw kolumny
label3.Text = db_read[1].ToString(); //bądź poprzez podanie numeru kolumny - liczenie od 0
Należy wspomnieć również o tym, że w przypadku, gdy zostanie osiągnięty ostatni indeks, dane przestaną być odczytywane. Warto w tej procedurze (jak i w pozostałych procedurach) wykorzystać składnię do przechwytywanie błędu try - catch, aby program nie zakończył swojego żywota. Aby po osiągnięciu ostatniego indeksu móc od początku odczytywać dane, należy wykonać procedurę odczytu od początku, tzn. odłączyć się od bazy danych, połączyć się z nią na nowo i wykonać zapytanie.
I to tyle z części programistycznej. Wydaje mi się, że nie jest to trudne zagadnie, więc początkujący raczej powinien dać radę ze zrozumieniem tego.
Po poprawnym skompilowaniu programu w folderze DEBUG naszego projektu znajduje się plik wykonywalny naszego projektu wraz z pozostałymi plikami. Poniżej na zdjęciach przedstawiam, jakie pliki muszą znaleźć się na innym komputerze aby program działał prawidłowo (wersja minimalistyczna i maksymalistyczna ).
Mam nadzieję, że w prosty i w przyjazny sposób udało mi się przedstawić obsługę biblioteki SQLite
W przypadku jakichś błędów, czy pytań pisać. Każda forma krytyki będzie motywująca;)
Jeszcze w załączniku przesyłam cały program wraz z komentarzami, aby każdy mógł sprawdzić jak to działa, oraz bardziej złożony program typu książka adresowa, która przedstawia w bardziej rozwinięty sposób obsługę bazy danych.
Program książka adresowa jest tylko programem demonstracyjnym, więc mogą wystąpić błędy w pewnych czynnościach których nie przewidziałem.
Z programów tych usunąłem folder package, aby mniej zajmował. Po ściągnięciu i rozpakowaniu projektu należy go najpierw skompilować. Brakuje pliki powinny zostać ściągnięte automatycznie z internetu (bądź z dysku jeżeli się na nim znajdują).