2011-04-03 16 views
7

Używam kwerend HQL w Hibernate i zastanawiałem się, czy mogę zwiększyć wydajność ponownych zapytań w aplikacji.Ponowne wykorzystanie zapytań w Hibernate

Zazwyczaj trzeba utworzyć nowy obiekt Query dla każdej sesji:

Session session; 
Query q1 = session.createQuery("select a from Article a where id=:id"); 
q1.setInteger("id",123); 
List result = q1.list(); 

Teraz mam stosunkowo złożonych zapytań w HQL, które nie chcą mieć analizowany w kółko. Czy istnieje sposób na utworzenie zapytania i ponowne użycie go w innej sesji? Tak:

Session session; 
Query q2 = q1.reattach(); 
q2.setInteger("id",123); 
List result = q2.list(); 

Jeśli Hibernate wykorzystuje sprawozdania przygotowanego tak, to powinno być godne przyrost wydajności, zwłaszcza w połączeniu z pula połączeń, które buforuje przygotowanych sprawozdań.

EDIT: Ponowne użycie zapytań w hibernacji zwykle nie jest potrzebne, ponieważ plan kwerend jest już buforowany w klasie mimo to QueryPlanCache. Kwerendy nazwane również nie zapewniają żadnej poprawy, ponieważ są używane tylko do wyszukiwania ciągu zapytania i żaden plan nie jest z nimi powiązany.

Podsumowując: Nie ma sensu ponownie wykorzystywać zapytania w hibernacji. Tylko pamiętaj, aby używać zapytań sparametryzowanych ZAWSZE, więc pamiętaj, aby buforowanie planu było małe.

+0

@allingeek: Na czym dokładnie? Po prostu otwórz QueryPlanCache ze źródła Hibernate. Albo co miałeś na myśli? – Daniel

+0

To, czego naprawdę szukałem, to ponowne użycie PreparedStatement. Przepuściłem konfigurację pamięci podręcznej instrukcji w c3p0 na podstawie twojego pytania i zapisałem dzień. Dzięki. – allingeek

Odpowiedz

4

Możesz użyć „kwerendę o nazwie”: Opisywanie swoją klasę Entity jak

@Entity 
@NamedQuery(name="Article.findById", query="select a from Article a where id=:id")  
public class Article{ ... 

a następnie zostanie on przeanalizowany raz podczas rozruchu, kiedy chcesz go używać po prostu zadzwonić:

session.getNamedQuery("Article.findById") 
     .setInteger("id",123); 
+1

Zaakceptowany, choć bezużyteczny :). Zobacz moją edycję na moje pytanie. – Daniel

0

Nazwana kwerenda jako described by Kiavash robi to, o co prosisz, ale wątpię, że daje ona jakąkolwiek istotną poprawę wydajności.

Przygotowane instrukcje są używane, jeśli baza danych je obsługuje, niezależnie od tego, czy używasz nazwanych kwerend Hibernacji, czy nie. Co najwyżej oszczędzasz kłopot z analizowaniem zapytania HQL. Kwerenda nazwana jest bardziej przeznaczona do ponownego użycia kodu.

+1

To była dokładnie moja intencja. Używam już przygotowanych wyciągów w bazie danych i wiem, że duża część pozostałego czasu procesora to praca nad HQL zapytania. – Daniel

Powiązane problemy