2.1 Wprowadzenie do klas Query

Nawiasem mówiąc, kolejnym ważnym punktem jest klasa pomocnicza Query. Mogłeś to zobaczyć na tym przykładzie:

public List<Employee> getAllEmployes() {
    try (Session session = sessionFactory.openSession()) {
            Query<Employee> query = session.createQuery("from Employee", Employee.class);
            return query.list();
    }
}

W rzeczywistości Query jest interfejsem i ma kilka implementacji dla różnych przypadków. Ale dla uproszczenia będę nadal nazywał to klasą. To jest, powiedzmy, klasa w szerokim tego słowa znaczeniu - w sensie OOP.

Notatka. Kiedyś były dwie klasy:

  • Zapytanie opisujące zapytanie.
  • TypedQuery, aby opisać zapytanie ze znanym typem.

Pierwszy pojawił się, gdy istniał już Hibernate i nie było jeszcze generyków. Następnie, po wydaniu JDK 5, do Hibernate została dodana kolejna klasa – TypedQuery, która już wspierała wpisywanie wyniku zapytania.

Ale, o ile pamiętam, począwszy od piątej wersji Hibernate, pozostała tylko jedna typowana klasa, która nazywa się teraz Query.

Standardowy sposób tworzenia zapytania to:


Query<Employee> query = session.createQuery("from Employee", Employee.class);

Nauczyłeś się tworzyć obiekty Query, ale jak wykonać te zapytania?

Tutaj sprawa jest jeszcze prostsza — po prostu wywołujemy metodę list() na obiekcie Query:


Query<Employee> query = session.createQuery("from Employee", Employee.class);
List<Employee> resultLіst = query.list();

Metoda list() ma synonim JPA, metodę, która robi to samo, ale nazywa się getResultList() . Czasami można to zobaczyć w kodzie napisanym przez innych programistów.

Nawiasem mówiąc, jeśli zapytanie sugeruje, że wynik będzie pojedynczym wynikiem, łatwiej jest użyć metody uniqueResult() do wywołania zapytania .


Query<Employee> query = session.createQuery("from Employee where id = 1", Employee.class);
Employee result = query.uniqueResult();

Metoda uniqueResult() ma synonim JPA, metodę singleResult() . Został wprowadzony w celu zapewnienia zgodności Hibernate ze standardem JPA. Robi dokładnie to samo.

2.2 Metody klasy zapytań

W rzeczywistości klasa Query ma wiele różnych metod. Poniżej omówię jeszcze trzy z nich.

Pierwsza to metoda stream() . I jego synonim JPA getResultStream() .

Obie te metody zwracają strumień danych zamiast listy. Takie podejście może być bardzo wydajne, gdy nie potrzebujesz jednocześnie wszystkich obiektów uzyskanych w wyniku zapytania. Lub istnieje możliwość, że wykorzystany zostanie tylko pierwszy z nich.

Przykład:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
Stream<Employee> stream = query.stream();

Drugą metodą jest metoda executeUpdate() . Możesz napisać zapytanie, które zmieni coś w bazie danych. W takim przypadku konieczne jest, aby Hibernate nie używał transakcji tylko do odczytu podczas uzyskiwania dostępu do bazy danych.

Przykład żądania: postanowiliśmy podnieść poziom wszystkich użytkowników o 1.


Query<User> query = session.createQuery("update User set level=level+1", User.class);
int count = query.executeUpdate();

Metoda executeUpdate() zwróci liczbę faktycznie zmodyfikowanych wierszy.

I wreszcie trzecią metodą jest scroll() . Powiemy Ci o tym trochę więcej.

2.3 Metody klas przewijania

Ta metoda jest nieco podobna do metody stream() . Tylko on umożliwia poruszanie się po liście wyników bez wyciągania wyników. Oznacza to, że możesz wykonać zapytanie, a następnie przewinąć je do milionowego wiersza wyniku i stamtąd rozpocząć odczytywanie danych.

Taki zaawansowany iterator.


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();

Obiekt ScrollableResults ma następujące metody:

metoda Opis
R get() Zwraca bieżący element
Następny() Przenosi wskaźnik do następnego elementu
poprzedni() Przenosi wskaźnik do poprzedniego elementu
przewiń (rozmiar int) Przewiń do przodu według linii rozmiaru
pozycja(int pozycja) Ustawia numer pozycji elementu jako bieżący element
ostatni() Bieżący element jest teraz ostatnim
Pierwszy() Bieżący element jest teraz pierwszym
getRowNumber() Zwraca bieżący numer linii
setRowNumber() Ustawia bieżący numer linii

Załóżmy, że uruchomiłeś zapytanie i chcesz uzyskać ostatni element. Oto jak to zrobić:


Query<Employee> query = session.createQuery("from Employee where id > 100", Employee.class);
ScrollableResults<Employee> scroll = query.scroll();
scroll.last();
Employee lastEmployee = scroll.get();