JPA i Hibernate-kryteria vs. JPQL lub HQL

Jakie są plusy i minusy stosowania kryteriów lub HQL ? Criteria API jest ładnym obiektowym sposobem wyrażania zapytań w Hibernate, ale czasami zapytania Criteria są trudniejsze do zrozumienia/zbudowania niż HQL.

Kiedy stosujesz kryteria a kiedy HQL? Co wolisz w jakich przypadkach? Czy to tylko kwestia gustu?

Author: Vlad Mihalcea, 2008-10-13

21 answers

Preferuję najczęściej zapytania o kryteria dla zapytań dynamicznych. Na przykład znacznie łatwiej jest dynamicznie dodawać niektóre zamówienia lub pozostawić niektóre części (np. ograniczenia) w zależności od jakiegoś parametru.

Z drugiej strony używam HQL do statycznych i złożonych zapytań, ponieważ jest o wiele łatwiejszy do zrozumienia / odczytania HQL. Również HQL jest nieco mocniejszy, myślę, że np. dla różnych typów złączy.

 201
Author: cretzel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-13 12:54:37

Istnieje różnica pod względem wydajności między HQL i criteriaQuery, za każdym razem, gdy odpalisz zapytanie za pomocą criteriaQuery, tworzy on nowy alias dla nazwy tabeli, który nie odzwierciedla w ostatnim zapytanym buforze dla żadnego DB. Prowadzi to do narzutu kompilacji wygenerowanego SQL, co zajmuje więcej czasu na wykonanie.

Odnośnie strategii pobierania [http://www.hibernate.org/315.html]

  • kryteria uwzględniają ustawienia lenistwa w mapach i gwarantuje, że to, co chcesz załadować, jest załadowane. Oznacza to, że jedno zapytanie kryteriów może skutkować kilkoma natychmiastowymi instrukcjami SQL SELECT, aby pobrać podgraf ze wszystkimi Nie leniwymi mapowanymi asocjacjami i kolekcjami. Jeśli chcesz zmienić "jak", a nawet "co", użyj setFetchMode (), aby włączyć lub wyłączyć zewnętrzne pobieranie połączeń dla określonej kolekcji lub powiązania. Kryteria również w pełni respektują strategię pobierania (join vs select vs subselect).
  • HQL szanuje ustawienia lenistwa w mapowaniach i gwarantuje, że to, co chcesz załadować, zostanie załadowane. Oznacza to, że jedno zapytanie HQL może skutkować kilkoma natychmiastowymi instrukcjami SQL SELECT, aby pobrać podgraf ze wszystkimi Nie leniwymi mapowanymi asocjacjami i kolekcjami. Jeśli chcesz zmienić "jak", a nawet "co", użyj LEFT JOIN FETCH, aby włączyć zewnętrzne pobieranie join dla określonej kolekcji lub nullable wiele-To-one lub jeden-To-one, lub JOIN FETCH, aby włączyć wewnętrzne pobieranie join dla nie nullable wiele-do-jednego lub jeden-do-jednego Stowarzyszenia. Zapytania HQL nie respektują żadnego fetch= "join" zdefiniowanego w dokumencie mapowania.
 88
Author: Varun Mehta,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-12-04 17:30:58

Criteria jest obiektowym API, podczas gdy HQL oznacza konkatenację łańcuchów. Oznacza to, że wszystkie korzyści płynące z zorientowania na obiekt mają zastosowanie:

  1. Wszystko inne jest równe, wersja OO jest nieco mniej podatna na błędy. Każdy stary ciąg znaków może zostać dołączony do zapytania HQL, podczas gdy tylko ważne obiekty Criteria mogą go przekształcić w drzewo kryteriów. W rzeczywistości klasy kryteriów są bardziej ograniczone.
  2. z auto-complete, OO jest bardziej wykrywalne (a tym samym łatwiejsze w użyciu, dla mnie przynajmniej). Nie musisz koniecznie pamiętać, które części zapytania idą gdzie; IDE może Ci pomóc
  3. nie musisz też pamiętać szczegółów składni (na przykład, które symbole idą gdzie). Wszystko, co musisz wiedzieć, to jak wywoływać metody i tworzyć obiekty.

Ponieważ HQL jest bardzo podobny do SQL (który większość programistów zna już bardzo dobrze), to te argumenty "nie muszą pamiętać" nie mają tak dużej wagi. Gdyby HQL był bardziej inny, to byłby bardziej importatnt.

 38
Author: Craig Walker,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-02-06 17:28:03

Zazwyczaj używam kryteriów, gdy nie wiem, jakie dane wejściowe będą używane na jakich fragmentach danych. Jak w formularzu wyszukiwania, gdzie użytkownik może wprowadzić dowolny z 1 do 50 pozycji i nie wiem, co będą szukać. Bardzo łatwo jest po prostu dodać więcej do kryteriów, gdy przechodzę przez sprawdzanie, czego szuka użytkownik. Myślę, że byłoby trochę bardziej kłopotliwe umieścić zapytanie HQL w tej sytuacji. HQL jest świetny, gdy wiem dokładnie, czego chcę.

 34
Author: Arthur Thomas,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-13 22:07:33

HQL jest o wiele łatwiejszy do odczytania, łatwiejszy do debugowania przy użyciu narzędzi takich jak wtyczka Eclipse Hibernate i łatwiejszy do zalogowania. Zapytania kryteriów są lepsze do budowania zapytań dynamicznych, w których wiele zachowań jest określanych w czasie wykonywania. Jeśli nie znasz SQL, mogę zrozumieć za pomocą zapytań kryteriów, ale ogólnie wolę HQL, Jeśli wiem, co chcę z góry.

 31
Author: Brian Deterling,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-13 15:28:07

Kryteria są jedynym sposobem na określenie wyszukiwań kluczy naturalnych, które wykorzystują specjalną optymalizację w buforze zapytań drugiego poziomu. HQL nie ma możliwości określenia niezbędnej podpowiedzi.

Więcej informacji znajdziesz tutaj:

 22
Author: Alex Miller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-07-10 07:21:51

Criteria Api jest jednym z dobrych pojęć Hibernate. według mnie są to nieliczne punkty, dzięki którym możemy odróżnić HQL i kryteria Api

  1. HQL ma wykonywać zarówno operacje select, jak i non-select na danych, ale Criteria służy tylko do wyboru danych, nie możemy wykonywać operacji non-select przy użyciu kryteriów.
  2. HQL jest odpowiedni do wykonywania zapytań statycznych, gdzie as Criteria jest odpowiedni do wykonywania dynamicznych Queries
  3. HQL nie obsługuje koncepcji paginacji , ale możemy osiągnąć paginację za pomocą kryteriów.
  4. kryteria używane do wykonywania więcej czasu niż HQL.
  5. z kryteriami jesteśmy bezpieczni z SQL Injection ze względu na dynamiczne generowanie zapytań, ale w HQL, ponieważ zapytania są stałe lub parametryzowane, nie ma bezpieczeństwa przed SQL Injection
 20
Author: Arvind,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-24 06:31:10

Dla mnie kryteria są dość łatwe do zrozumienia i tworzenia dynamicznych zapytań. Ale wadą, którą mówię do tej pory jest to, że ładuje wszystkie relacje many - one itp, Ponieważ mamy tylko trzy typy FetchModes tj. Select, Proxy i Default i we wszystkich tych przypadkach ładuje wiele-one (może się mylę, jeśli tak mi pomóż:))

Drugi problem z kryteriami polega na tym, że ładuje kompletny obiekt tzn. jeśli chcę tylko załadować EmpName pracownika to nie wymyślę tego wstawionego to wymyślę pełnego pracownika obiekt i mogę uzyskać z niego EmpName dzięki temu to naprawdę źle działa w raportowaniu . gdzie jako HQL po prostu załaduj (Nie załaduj skojarzeń / relacji) co chcesz, aby zwiększyć wydajność wiele razy.

Jedną z cech kryteriów jest to, że będzie bezpieczne u z SQL Injection ze względu na jego dynamiczne generowanie zapytań, gdzie jak w HQL jako zapytania ur są albo stałe lub parametryzowane, więc nie są bezpieczne od SQL Injection.

Również jeśli piszesz HQL w ur aspx.pliki cs, wtedy jesteś mocno związany z ur DAL.

Ogólnie mój wniosek jest taki, że są miejsca, w których nie można żyć bez HQL jak raporty, więc korzystanie z nich inne kryteria jest łatwiejsze do zarządzania.

 13
Author: Zafar,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-22 17:09:39

Aby wykorzystać to, co najlepsze z obu światów, wyrazistość i zwięzłość HQL oraz dynamiczny charakter kryteriów należy rozważyć użycie Querydsl .

Querydsl obsługuje JPA/ Hibernate, JDO, SQL i Collections.

Jestem opiekunem Querydsl, więc ta odpowiedź jest stronnicza.

 12
Author: Timo Westkämper,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-02-02 09:24:20

Dla mnie największą wygraną na kryteriach jest przykładowe API, gdzie można przekazać obiekt i hibernate zbuduje zapytanie na podstawie tych właściwości obiektu.

Poza tym, criteria API ma swoje dziwactwa (myślę, że zespół hibernate przerabia api), takie jak:

  • A kryteria.createAlias ("obj") wymusza połączenie wewnętrzne zamiast możliwego połączenia zewnętrznego
  • nie można utworzyć dwa razy tego samego aliasu
  • niektóre klauzule sql nie mają prostego odpowiednika kryteriów (jak subselect)
  • itd.

Zazwyczaj używam HQL, gdy chcę zapytania podobne do sql (delete from Users where status='blocked'), i używam kryteriów, gdy nie chcę używać dodawania łańcuchów.

Kolejną zaletą HQL jest to, że można zdefiniować wszystkie zapytania przed ręką, a nawet zewnętrznie je do pliku lub tak.

 11
Author: Miguel Ping,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-10-14 12:56:33

Criteria API zapewniają jedną odrębną funkcję, której nie zapewnia ani SQL, ani HQL. ie. umożliwia sprawdzanie czasu kompilacji zapytania.

 9
Author: user1165443,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-01-23 17:12:14

Criteria API jest lepiej dostosowane do dynamicznie generowanych zapytań, gdy filtry zapytań są dynamicznie stosowane w czasie wykonywania. Dlatego, aby zapobiec atakom SQL Injection podczas budowania dynamicznych zapytań, Criteria API jest bardzo dobrym wyborem.

Zapytania o kryteria są mniej wyraziste i można łatwo skończyć z bardzo skomplikowanym i nieefektywnym zapytaniem wygenerowanym przez SQL . Kiedyś dołączyłem do dużej aplikacji korporacyjnej, gdzie Criteria API była domyślną metodą zapytań, a nie nawet obszerne przeglądanie kodu może przezwyciężyć horror nie wiedząc, jakie zapytania SQL zamierzamy skończyć.

JPQL lub HQL jest znacznie bardziej wyrazisty i znacznie łatwiej przewidzieć powiązane wygenerowane zapytanie SQL. Znacznie łatwiej jest również przejrzeć własne zapytania HQL niż kryteria.

Większość przypadków użycia zapytań encji nie wymaga klauzul dynamic where, więc możesz zaimplementować większość zapytań z JPQL, pozostawiając kryteria dla dynamicznych.

Warto zaznaczając, że wybieranie jednostek z JPQL lub Criteria API ma sens, jeśli trzeba je zmodyfikować. W przeciwnym razie projekcja DTO działa lepiej. Sprawdź Ten artykuł, aby uzyskać więcej informacji .

 9
Author: Vlad Mihalcea,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-04 12:02:12

Na początku używaliśmy głównie kryteriów w naszej aplikacji, ale po jej zastąpieniu HQL ze względu na problemy z wydajnością.
Głównie używamy bardzo złożonych zapytań z kilkoma połączeniami, co prowadzi do wielu zapytań w kryteriach, ale jest bardzo zoptymalizowane w HQL.
Chodzi o to, że używamy tylko kilku propeties na konkretnym obiekcie, a nie kompletnych obiektach. Z kryteriami problemem była także konkatenacja łańcuchów.
Powiedzmy, że jeśli chcesz wyświetlić imię i nazwisko użytkownika w HQL jest to dość proste (name || ' ' || surname), ale w Crterii nie jest to możliwe.
Aby to przezwyciężyć, użyliśmy ResultTransormers, gdzie istniały metody, w których taka konkatenacja została zaimplementowana dla potrzebnego rezultatu.
Dzisiaj używamy głównie HQL w ten sposób:

String hql = "select " +
            "c.uuid as uuid," +
            "c.name as name," +
            "c.objective as objective," +
            "c.startDate as startDate," +
            "c.endDate as endDate," +
            "c.description as description," +
            "s.status as status," +
            "t.type as type " +
            "from " + Campaign.class.getName() + " c " +
            "left join c.type t " +
            "left join c.status s";

Query query =  hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();

Więc w naszym przypadku zwracane rekordy są mapami potrzebnych właściwości.

 7
Author: Bojan Kraut,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-10-27 10:29:00
  • HQL ma wykonywać operacje select i non-select na danych, ale kryteria są tylko do wyboru danych, nie możemy wykonywać operacji non-select przy użyciu kryteriów
  • HQL jest odpowiedni do wykonywania zapytań statycznych, gdzie as Criteria jest odpowiedni do wykonywania zapytań dynamicznych
  • HQL nie obsługuje koncepcji paginacji, ale możemy osiągnąć paginację za pomocą kryteriów
  • kryteria używane, aby wykonać więcej czasu niż HQL
  • z kryteriami jesteśmy bezpieczni z SQL Injection ze względu na dynamiczne generowanie zapytań, ale w HQL, ponieważ zapytania są stałe lub parametryzowane, nie ma bezpieczeństwa przed SQL Injection.

Źródło

 7
Author: Premraj,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-06-17 10:39:27

Criteria query dla dynamicznie możemy konstruować zapytania w oparciu o nasze inputs..In case of HQL query is the static query once we construct we can ' t change the structure of the query.

 5
Author: user1679378,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-25 06:54:06

Nie chcę kopać martwego konia tutaj, ale ważne jest, aby wspomnieć, że kryteria zapytania są teraz przestarzałe. Użyj HQL.

 4
Author: Eskir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-14 08:48:21

Preferuję również zapytania o kryteria dla zapytań dynamicznych. Ale ja wolę hql dla delete queries, na przykład jeśli delete all records from child table for parent id 'xyz', to jest łatwo osiągane przez HQL, ale dla criteria API najpierw musimy odpalić n number of delete queries gdzie n jest number of child table records.

 1
Author: Punit Patel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-18 09:36:06

Większość odpowiedzi tutaj są mylące i wspomnieć, że {[0] } są wolniejsze niż HQL, co w rzeczywistości nie jest przypadek.

Jeśli zagłębisz się głęboko i wykonasz kilka testów, zobaczysz zapytania o kryteria działają znacznie lepiej niż zwykłe HQL.

A także z Criteria Query otrzymujeszobiektową kontrolę , której nie ma zHQL .

Aby uzyskać więcej informacji przeczytaj tę odpowiedź tutaj .

 0
Author: Pritam Banerjee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:18:14

Jest inny sposób. Skończyło się na stworzeniu parsera HQL opartego na oryginalnej składni hibernate, aby najpierw parsował HQL, a następnie mógł dynamicznie wstrzykiwać dynamiczne parametry lub automatycznie dodawać popularne filtry dla zapytań HQL. Działa świetnie!

 0
Author: Wallace Peng,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-01-12 19:00:38

Ten post jest dość stary. Większość odpowiedzi mówi o kryteriach hibernacji, a nie o kryteriach JPA. JPA 2.1 dodał CriteriaDelete/CriteriaUpdate oraz EntityGraph, który kontroluje co dokładnie pobrać. Criteria API jest lepsze, ponieważ Java jest OO. Dlatego powstaje JPA. Po skompilowaniu JPQL zostanie przetłumaczony na drzewo AST(model oo) przed przetłumaczeniem na SQL.

 0
Author: Sunnyday,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-25 03:51:59

HQL może powodować Bezpieczeństwo problemy takie jak SQL injection.

 -3
Author: Emad Aghayi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-06 06:14:29