Czy w Hibernacji 3 można zrobić równowartość następującego limitu MySQL w HQL?
select * from a_table order by a_table_column desc limit 0, 20;
Nie chcę używać setMaxResults, jeśli to możliwe. Było to zdecydowanie możliwe w starszej wersji Hibernacji / HQL, ale wydaje się, że zniknęło.
java
hibernate
hql
hibernate3
stevedbrown
źródło
źródło
Hibernate-5.0.12
. Czy to wciąż nie jest dostępne? Byłoby naprawdę ciężko zdobyć około miliona rekordów, a następnie zastosować na nim filtr -setMaxResults
jak zauważył @Rachel w odpowiedzi @skaffman.Odpowiedzi:
Zostało to opublikowane na forum Hibernate kilka lat temu, gdy zapytano go, dlaczego to działa w Hibernacji 2, ale nie w Hibernacji 3:
Więc jeśli zadziałało w Hibernacji 2, wygląda na to, że był to przypadek, a nie projekt. Myślę, że było tak, ponieważ parser Hibernacji 2 HQL zastąpiłby bity zapytania, które rozpoznał jako HQL, i zostawił resztę bez zmian, abyś mógł się zakraść w natywnym SQL. Hibernacja 3 ma jednak odpowiedni parser AST HQL i jest o wiele mniej wybaczający.
Myślę,
Query.setMaxResults()
że to naprawdę twoja jedyna opcja.źródło
setMaxResults
a następnie wywoływany zestaw wyników, który pobierałby ograniczoną liczbę wierszy wyników od zestawu wyników i wyświetlał go użytkownikowi, w moim przypadku mam 3 miliony rekordów, które są wyszukiwane, a następnie wywołuję setMaxResults, aby ustawić 50 rekordów, ale nie chcę tego robić, podczas gdy samo zapytanie chcę zapytać o 50 rekordów, czy jest na to sposób?setMaxResults
hibernacją dodalimit
część do zapytania. Nie uzyska wszystkich wyników. Możesz sprawdzić zapytanie, które generuje, włączając:<property name="show_sql">true</property>
źródło
setFirstResult
jest on rzeczywiście wymieniony w tej odpowiedzi, podczas gdy tutaj i gdzie indziej mówią tylkosetMaxResults
to isetMaxResults
to bez wspominania, jak ustawić przesunięcie.Jeśli nie chcesz używać
setMaxResults()
tegoQuery
obiektu, zawsze możesz wrócić do używania normalnego SQL.źródło
Jeśli nie chcesz używać setMaxResults, możesz także użyć Query.scroll zamiast listy i pobrać żądane wiersze. Przydatne na przykład dla stronicowania.
źródło
setMaxResults()
najpierw ładuje każdy rekord w pamięci, a następnie tworzy listę podrzędną, która, gdy jest sto tysięcy lub więcej rekordów, powoduje awarię serwera, ponieważ brakuje pamięci. Mogłem jednak przejść z zapytania o typie JPA do zapytania Hibernacja,QueryImpl hibernateQuery = query.unwrap(QueryImpl.class)
a następnie mogłem użyćscroll()
metody zgodnie z sugestią.Możesz w tym celu łatwo zastosować podział na strony.
musisz przejść,
new PageRequest(0, 1)
aby pobrać rekordy, a z listy pobierz pierwszy rekord.źródło
setFirstResult
IsetMaxResults
Query
metodyDla JPA i hibernacji
Query
ThesetFirstResult
metoda jest równoważneOFFSET
, asetMaxResults
sposób jest odpowiednikiem dopuszczalnych:LimitHandler
abstrakcjaHibernacja
LimitHandler
definiuje logikę stronicowania specyficzną dla bazy danych i jak pokazano na poniższym diagramie, Hibernacja obsługuje wiele opcji stronicowania specyficznych dla bazy danych:Teraz, w zależności od bazowego systemu relacyjnej bazy danych, którego używasz, powyższe zapytanie JPQL będzie używać właściwej składni stronicowania.
MySQL
PostgreSQL
SQL Server
Wyrocznia
Zaletą używania
setFirstResult
isetMaxResults
jest to, że Hibernacja może generować specyficzną dla bazy danych składnię stronicowania dla dowolnych obsługiwanych relacyjnych baz danych.I nie jesteś ograniczony tylko do zapytań JPQL. Możesz użyć metody
setFirstResult
isetMaxResults
siódmej do natywnych zapytań SQL.Natywne zapytania SQL
Podczas korzystania z rodzimych zapytań SQL nie trzeba kodować stronicowania specyficznego dla bazy danych. Hibernacja może dodać to do twoich zapytań.
Jeśli więc wykonujesz to zapytanie SQL na PostgreSQL:
Hibernacja przekształci go w następujący sposób:
Fajnie, prawda?
Podział na strony poza SQL
Podział na strony jest dobry, gdy można indeksować kryteria filtrowania i sortowania. Jeśli twoje wymagania stronicowania wymagają dynamicznego filtrowania, o wiele lepiej jest zastosować rozwiązanie z indeksem odwróconym, takie jak ElasticSearch.
Sprawdź ten artykuł, aby uzyskać więcej informacji.
źródło
String hql = "select userName from AccountInfo order by points desc 5";
To działało dla mnie bez użycia
setmaxResults();
Wystarczy podać maksymalną wartość w ostatnim (w tym przypadku 5) bez użycia słowa kluczowego
limit
. : Pźródło
Moje spostrzeżenie jest takie, że nawet ty masz limit w HQL (hibernacja 3.x), będzie to albo powodować błąd parsowania, albo po prostu zostanie zignorowany. (jeśli masz zamówienie przez + desc / asc przed limitem, zostanie zignorowane, jeśli nie masz desc / asc przed limitem, spowoduje błąd parsowania)
źródło
Jeśli można zarządzać limitem w tym trybie
To jest naprawdę prosty kod do obsługi limitu lub listy.
źródło
źródło
Musisz napisać natywne zapytanie, zapoznaj się z tym .
źródło
Możesz użyć poniższego zapytania
źródło
Poniższy fragment służy do wykonywania zapytań o limit przy użyciu HQL.
Możesz pobrać aplikację demonstracyjną pod tym linkiem .
źródło
źródło