ZSBD-2st-1.2-lab5.tresc-1.3-Slajd8
Odczytywanie obiektów
W celu pokazania jak można odczytywać obiekty z bazy danych, załóżmy, że poprzedni program został uruchomiony i do bazy danych został zapisany obiekt klasy Triangle, którego wartości pól color i side to odpowiednio „Blue” i 10.
Pierwszą czynnością, jaką należy wykonać, przed odczytaniem obiektów z bazy danych, jest zaimportowanie dwóch klas, które będą wykorzystywane (List i Iterator) (1). W celu odczytania obiektów z bazy danych należy wykonać do niej zapytanie. Biblioteki db4o pozwalają na wykonywanie zapytań na trzy sposoby: zapytanie przez przykład (ang. Query By Example , QBE), zapytanie natywne (ang. Native Query ) i za pomocą SODA API. QBE jest najprostszym sposobem wykonywania zapytań, ale posiadającym niestety dużo ograniczeń. Zapytania natywne są głównym sposobem wykonywania zapytań w bazie danych db4o. SODA API jest wewnętrznym interfejsem bibliotek db4o, a jego używanie do wykonywania zapytań jest odradzane. Slajd pokazuje sposób wykonania zapytania za pomocą metody QBE. Zapytania natywne i interfejs SODA API są poza zakresem ćwiczeń.
Drugą modyfikacją poprzedniego programu, jaką należy wykonać, jest zastąpienie fragmentu programu oznaczonego przez (3) na poprzednim slajdzie kawałkiem kodu, który oznaczono na tym slajdzie jako (2). Właściwe zapytanie jest wykonywane za pomocą dwóch instrukcji oznaczonych na slajdzie przez (3). Pierwsza z nich tworzy obiekt klasy Triangle, który jest „przykładem” według którego mają być wyszukiwane obiekty w bazie danych. Druga linijka wywołuje metodę get interfejsu ObjectContainer, która powoduje odszukanie wszystkich obiektów „pasujących” do przykładu. Pasowanie obiektów do przykładu można zdefiniować następująco. Wszystkie pola obiektów, które mają zostać zwrócone w wyniku zapytania, muszą mieć takie same wartości, jak pola obiektu - przykładu, pod warunkiem, że wartość danego pola przykładu nie jest domyślna. Przykładowo, wartością domyślną dla pola typu String jest null, a dla pola typu int jest 0. Ponieważ utworzono przykład, który polu kolor (String) miał przypisane null, a polu side wartość 10, to zapytanie miało odszukać wszystkie obiekty, klasy Trójkąt, których bok miał długość 10 (kolor pomijamy, ponieważ przykład miał w polu kolor wartość domyślną, czyli null). W wyniku realizacji metody get zwracana jest kolekcja obiektów (interfejs List<E>) spełniających warunki zapytania. Zwrócona kolekcja jest przeglądana za pomocą iteratora w pętli (4). Jeżeli przeglądana baza danych jest wynikiem działania programu z poprzednich slajdów, to wynik działania tego programu będzie wyglądał tak, jak to przedstawiono na fragmencie slajdu oznaczonym przez (5).
Należy zwrócić tutaj uwagę na jedną, ważną własność db4o. Otóż, jeżeli w wyniku zapytania zostanie zwrócony obiekt, który został już wcześniej odczytany z bazy danych, to nie zostanie utworzona w pamięci jego kopia, a zapytanie zwróci jedynie referencję na obiekt znajdujący się już w pamięci. Nie ma zatem obaw, że w wyniku wielokrotnego wykonywania zapytań w bazie danych jakieś obiekty zduplikują się.
Poniżej przedstawiono kilka przykładowych zapytań typu QBE:
1. Znajdź wszystkie niebieskie trójkąty (pole side ma wartość domyślną równą 0).
Triangle template=new Triangle(„Blue”,0);
List<Triangle> result=db.get(template);
2. Znajdź wszystkie trójkąty (zarówno kolor jak i długość boku mają wartość domyślną).
Triangle template=new Triangle(null,0);
List<Triangle> result=db.get(template);
3. Znajdź wszystkie trójkąty.
List<Triangle> result=db.get(Triangle.class);
Powyższy przykład wymaga wytłumaczenia. Otóż, metoda get posiada również wersję, w której zamiast obiektu – przykładu, jako parametr podaje się obiekt reprezentujący klasę obiektów, które mają zostać odszukane (obiekt ten można uzyskać np. za pomocą operatora class). Ponieważ tutaj, jako parametr podajemy obiekt reprezentujący klasę Triangle, to wszystkie obiekty klasy trójkąt zostaną odczytane.
4. Znajdź wszystkie kształty.
List<VisibleShape> result=db.get(VisibleShape.class);
Powyższy przykład jest bardzo podobny do poprzedniego. Zapytaniem tym odszukujemy wszystkie obiekty klasy VisibleShape. Ponieważ klasa Triangle dziedziczy z klasy VisibleShape, to obiekty klasy Triangle również znajdą się w wynikowej kolekcji.
5. Odczytaj wszystkie obiekty.
List<Object> result=db.get(null);
Jeżeli metodzie get zostanie przekazany parametr null, to odczytywane są wszystkie obiekty z bazy danych. Dlatego też, powyższe zapytanie zwraca wszystkie obiekty zapisane w bazie danych.
Kompletny kod programu, którego fragmenty pokazano na slajdzie załączono do kursu w postaci pliku: Skeleton-lab5.3.java