Porównanie mechanizmów stronicowania wyników zapytania
Istotnym elementem typowej aplikacji jest przetwarzanie, np. wyświetlanie, pewnej listy obiektów będącej wynikiem wyszukiwania w bazie danych. Bardzo często zdarza się, że jednorazowo potrzebny jest tylko pewien fragment tej listy, np. 10 najnowszych zamówień. Technologia trwałości danych powinna umożliwiać i ułatwiać pobieranie tylko pewnego podzbioru (strony) wyników zapytania i pobieranie kolejnych podzbiorów (stron) w miarę potrzeby. Poniżej pokażę, w jaki sposób implementację stronicowania wyników zapytania wspierają technologie (i specyfikacje) Hibernate, JPA, JDO, JDBC oraz Apache iBATIS Data Mapper. Jest to drugie z kryteriów porównania technologii trwałości danych, jakie tutaj prezentuję. Pierwszym było porównanie ze względu na wsparcie dla budowania dynamicznych zapytań. Wpierw, w artykule "Dynamiczne zapytania i selekcja poprzez przykład czyli Hibernate nokautuje JPA" porównałem Hibernate i JPA. Potem dodałem jeszcze wpis o iBATIS’ie w artykule "Dynamiczne zapytania z Apache iBATIS Data Mapper". Zapraszam do lektury, zwłaszcza, jeśli swoje wybory technologii lubisz opierać na konkretnych przesłankach.
Hibernate
Technologia Hibernate oferuje bardzo wygodny mechanizm stronicowania wyników zapytań. Mechanizm ten jest zaimplementowany na poziomie funkcji interfejsu programisty, nie na poziomie języka zapytań, stronicowanie rezultatu zapytania jest więc niezależne od treści samego zapytania. Fragment kodu pobierający drugą dziesiątkę zamówień (klasa Order) posortowanych po dacie złożenia zamówienia (atrybut placedDate) wygląda następująco:
Query query =
session.createQuery("FROM Order order ORDER BY order.placedDate");
query.setFirstResult(10);
query.setMaxResults(10);
Listorders = query.list();
Uruchomienie powyższego kodu spowoduje wygenerowanie odpowiedniego zapytania SQL, uwzględniającego specyfikę danej bazy danych. Hibernate wspiera bardzo wiele relacyjnych baz danych i ich dialekty języka SQL.
JPA - Java Persistence API
Wsparcie dla stronicowania oferowane przez specyfikacje Java Persistence API jest niemal identyczne jak w przypadku technologii Hibernate. Fragment kodu pobierający drugą dziesiątkę zamówień (klasa Order) posortowanych po dacie złożenia zamówienia (atrybut placedDate) wygląda następująco:
Query query = eManager.createQuery
("SELECT order FROM Order order ORDER BY order.placedDate");
query.setFirstResult(10);
query.setMaxResults(10);
Listorders = query.getResultList();
JDO - Java Data Objects
Technologia Java Data Objects wspiera stronicowanie wyników zapytania poprzez odpowiednie konstrukcje samego języka zapytań. Samo zapytanie może być wyrażone na dwa sposoby; w postaci pojedynczego obiektu klasy String definiującego jego treść lub poprzez ciąg wywołań odpowiednich funkcji interfejsu programisty. Stosując drugą z możliwości fragment kodu pobierający zamówienia (klasa Order) od 10. do 20. sortując po dacie złożenia zamówienia (atrybut placedDate) wygląda następująco:
Query query = pManager.newQuery(Order.class);
query.setOrdering("placedDate ASC");
query.setRange(10, 20);
Collectionorders = (Collection ) query.execute();
Możliwe jest także zdefiniowanie zakresu stronicowania jako zmiennych, a następnie wywoływanie wielokrotnie tego samego zapytania z podaniem różnych wartości. Analogiczna do powyższej funkcjonalność byłaby wtedy zaimplementowana następująco:
Query query = pManager.newQuery(Order.class);
query.setOrdering("placedDate ASC");
query.setRange(":1, :2");
Collectionorders = (Collection ) query.execute(10, 20);
Stosując podejście z zapytaniem wyrażonym jako pojedynczy napis analogiczny kod wygląda następująco:
Query query = pManager.newQuery
("SELECT FROM Order ORDER BY placedDate ASC RANGE :1, :2");
Collectionorders = (Collection ) query.execute(10, 20);
JDBC
Technologia JDBC służy do uruchamiania zapytań SQL i pobierania ewentualnych wyników tych zapytań. Zapytania są przekazywane do uruchomienia w niezmienionej formie, zatem technologia ta nie oferuje żadnych ułatwień dla implementacji stronicowania wyników zapytań. Elementy składni języka SQL służące do implementacji stronicowania nie są objęte odpowiednim standardem, tak więc zapytanie pobierające określony fragment normalnego wyniku może mieć różną postać w zależności od użytego systemu zarządzania bazą danych. Zapytanie SQL pobierające drugą dziesiątkę zamówień (z tabeli ORDER) posortowanych po dacie złożenia zamówienia (kolumna PLACED_DATE), zgodne ze składnią akceptowaną przez bazy danych MySQL i PostgreSQL wyglądałoby następująco:
SELECT * FROM ORDER
ORDER BY PLACED_DATE
LIMIT 10 OFFSET 10
Apache iBATIS Data Mapper
Technologia iBATIS Data Mapper nie generuje zapytań SQL a jedynie uruchamia te zdefiniowane przez programistę. Implementując stronicowanie trzeba więc posługiwać się takimi samymi metodami jak w przypadku użycia JDBC. Ograniczanie zakresu wyniku zapytania musi być zaimplementowane w zapytaniu SQL, w sposób właściwy dla używanej bazy danych.