Hibernate i HQL (pytanie o zaawansowane zapytania)

0

Wiam.
Od niedawna bawię się java Swing i teraz hibernate.
Proszę mi powiedzieć czy ja dobrze rozumuje:

Hibernate pozwala na korzystanie z bazy danych dzięki pracy na obiektach. Tylko nie do końca wiem jak HQL działa. Czy może chodzi o to, że w przypadku zaawansowanych zapytań (np. getSomethingByStatus)??

Proszę o odpowiedź mądrzejszych niz ja ludzi:)

0

Wiam.
Od niedawna bawię się java Swing i teraz hibernate.
Proszę mi powiedzieć czy ja dobrze rozumuje:

Hibernate pozwala na korzystanie z bazy danych dzięki pracy na obiektach. Tylko nie do końca wiem jak HQL działa. Czy może chodzi o to, że w przypadku zaawansowanych zapytań (np. getSomethingByStatus)trzeba uzyc HQL??

Proszę o odpowiedź mądrzejszych niz ja ludzi:)

EDIT: przepraszam za dubla, ale piewszy post zle napisalem

0

No nie samym HQLem człowiek żyje.

Po pierwsze jest takie coś jak EntityManager i jeżeli poprosisz go o to by np. znalazł kota o podanym identyfikatorze to wystarczy napisać:

em.find(Cat.class, catId);

On zamieni to na odpowiednie zapytanie SQL, a wynik zmapuje na obiekt klasy Cat.

Po drugie można użyć HQL czyli języka podobnego do SQLa:

em.createQuery("Select cat from Cat where cat.catId=?").setParameter(1, catId).getSingleResult();

Po trzecie można użyć Criteria API, czyli zestawu interfejsów i klas, które pozwalają na budowanie zapytań HQL, ale jednocześnie zabezpieczają przed literówkami, a to dzięki kontroli typów:

CriteriaQuery<Cat> criteria = builder.createQuery( Cat.class );
Root<Cat> cat = criteria.from( Cat.class );
criteria.select( cat );
criteria.where( builder.lt( cat.get( Cat_.catId ), catId ) );
Cat garfield = em.createQuery( criteria ).getSingleResult(); 

Po czwarte można użyć jeszcze native query, czyli za pomocą EM wywołać zwykłe zapytania SQL. Tylko po co ;)

Moje pytanie - co rozumiesz przez "zaawansowane zapytanie"?

0

Dziękuję za odpowiedź!

Tylko do czego służy w tkaim razie HQL? Po prosut jest to zamiennik? Czy można w nim wykonać rzeczy, których w inny sposób nie można? No, bo skoro jest hibernate, które pozwala na używanie obiektów to po co w ogóle zajmować się HQL?

0

W HQL można pisać bardziej skomplikowane zapytania, których nie można przedstawić obiektowo. Szczególnie jakieś złożone joiny, funkcje agregujące, itp.
Mając do dyspozycji Criteria API teoretycznie HQL nie jest potrzebny. Jednak jest on starszy niż CA i wywodzi się z czegoś takiego jak EJB Query Language, który powstał w czasach gdy królowało EJB 2 (dawno temu, legendy mówią że niewiele wcześniej powstał COBOL). Obecnie jest on utrzymywany w celu zapewnienia wstecznej zgodności oraz dlatego, że CA czasami jest "sztuką dla sztuki" i w HQL jest łatwiej napisać zapytanie.

0

Wszedzie pisza zeby zazwyczaj stosowac HQL / JPQL poniewaz sa czytelne, natomiast Criteria powinno sie stosowac do generatorow zapytan, np jakas stronka ktora pozwala tworzyc zapytania. Sam spojrz na swoje przyklady i powiedz ktore jest latwiejsze w utrzymaniu...

0

@mućka w moim przypadku to CA jest wygodniejsze. Za dużo litreówek robię :) CA zapewnia kontrolę typów co na dłuższą metę jest opłacalne.

0

Ciekawe czy Twoi koledzy maja podobne zdanie. Albo ci, ktorzy ten kod pozniej musza utrzymywac. Ale Ok, Twoja brocha, trzeba sie z nia liczyc.

0

@mućka, właśnie z powodu tych cholernych błędów w zapytaniach przeszliśmy na CA. Wszystko to kwestia odpowiedniego formatowania kodu tak by miał łatwą w odczycie strukturę. Poza tym nikt nie każe budować dużych zapytań w ramach jednej metody. Trochę refaktoryzacji typu extract method i dobre nazewnictwo do tego.

0

Kompletnie sie nie zgadzam - API nigdy nie zastapi DSL. CA to marne, rozbuchane API (plus zestaw stalych z meta-modelu np. Person_.lastName - sorry, ale WTF? tak tak to wina Javy ze nie ma pol i metod jako first-class citizens, dlatego pora zmienic jezyki) ktore calkowicie rozmazuje i przyslania sens kodu - na pierwszy rzut oka nawet ten Twoj przyklad jest kompletna nie wiadomo (ok, zaraz mi powiesz ze Ty czytasz to jak poemat, a ja jestem niekumaty...); SQL / HQL czy tam JPQL to swietne DSL do wydobywania danych: zwiezle, znane, nie wprowadzaja zbednego halasu.
Statyczne typowanie jest przeceniane ;d (tak, wiem ze to kontrowersyjne stwierdzenie, ale kto nie probowal nic innego, nie moze sie wypowiadac). Co do zapytan, jak juz raz je napiszesz porzadnie (co jest o wiele latwiejsze niz by sie wydawalo), to po prostu dzialaja. Co innego jakies CA ktore chcesz rozbijac na wiele metod - WTF?

0

@mućka, zmiana języka fajna sprawa, ale nie taka prosta.
Próbowałem dynamicznego typowania zarówno w php (+JS i to w czasach gdy pytanie dotyczące JS nie zaczynało się od "piszę w jQuery i...") jak i w ruby. Na krótką metę fajne. Na dłuższą niestety zdradliwe.
CA jest po prostu łatwe do przetestowania "po kawałku" i w dodatku można tworzyć reużywalne elementy zapytań, co też jest dużym plusem.

0

Odświeżam temat, bo mam dylemat.
Czy jak już korzystam z Hibernate to powinienm robić klasy Modelu (DAO?)? Czy hibenrate jest już na tyle elastyczny, że nie muszę tego tworzyć?

W tej chwili planuje stworzyć takie klasy (na przykłądzie fikcyjnej klasy "Pracownik"):

Pracownik.java - javabean do obsługi hibernate
PracownikController.java - główny plik sterująćy całym mechanizmem

  • widoki (np. PracownikDetailsView.java)

Może o czyms zapomnialem?? Prosze o wyrozumialosc! Przejscie z php na Jave to naprawdę jest "zderzenie z rzeczywistością"

0

Sam Hibernate dostarcza w ramach Hibernate Tools narzędzi do generowania klas Java ze schematu bazy danych.
Jeżeli chcesz uzyskać narzędzie, które poza wygenerowaniem klas modelu stworzy też m.n. kontrolery i widoki na takiej zasadzie jak w RoR (ruby), a w php w Symfony to polecam przyjrzeć się Spring Roo oraz Play Framework.

Generalnie w javie na początek trzeba na raz ogarnąć w minimalnym stopniu bardzo dużo narzędzi o ile chcesz tworzyć aplikacje webowe.

0
Koziołek napisał(a)

Sam Hibernate dostarcza w ramach Hibernate Tools narzędzi do generowania klas Java ze schematu bazy danych.

Tak i właśnie mi się taka klasa wygenerowała. Myślę sobie teraz czy ona już zastąpi mi całkowicie klasę, która miałaby reprezentować obiekt pracownika.

Czyli kontroller używa klasy wygenerowanej przez hibernate do pobrania danych, a potem przekazuje je do widoku.

Piszę przykładowy porgramik bazodanowy po to, żeby się nauczyć i próbuję sobie to ułożyć jakoś, bo zakładam, że większy program pewnie wymagałby innych rozwiązań.

0

Taka klasa zawiera tylko mapowanie - odpowiada strukturze z bazy danych. Zatem z jednej strony reprezentuje ona Pracownika w bazie danych, ale z drugiej wszystkie operacje wykonywane na tej klasie trzeba samodzielnie zaprogramować.

0

No właśnie i chciałem to upchnąć do kontrolera, no bo w sumie nie jest to jakoś dużo kodu. Czyli mniej więcej coś takiego(pomijam już pobranie sesji itp - ten kod prawie,że skopiowany ze strone hibernate)

session = sessionFactory.openSession();
session.beginTransaction();
Pracownik p = (Pracownik)session.get(Pracownik.class, 1); // Nie mam jeszcze pojecia czy ta linia zadziala, ale powiedzmy, ze o cos tkaiego mi chodzi
pracownikDetails d = new pracownikDetails(p);
session.getTransaction().commit();
session.close();
0

Nie do kontrolera :) Utwórz klasę PracownikDao i tam upchnąć operacje na encji Pracownik. W ten sposób będziesz mógł używać tego kodu w wielu różnych miejscach.

0

Dziękuję za pomoc!
Póki co wiem co mam robic.

0
Koziołek napisał(a)

Po czwarte można użyć jeszcze native query, czyli za pomocą EM wywołać zwykłe zapytania SQL. Tylko po co ;)

a czasami chociaz by po to zeby dodać hinta do zapytania czego nie zrobisz w hql ani criteriaApi:)

0

@kemot, no wiem, wiem :D do tego za pomocą NQ można wysyłać zoptymalizowane zapytania :) tyle tylko, że to już jest trochę wyższa szkoła jazdy czy to w Hibernate czy to w JPA2

1 użytkowników online, w tym zalogowanych: 0, gości: 1