JPA: das Zwischenspeichern von Abfragen
Ich bin mit JPA laden und speichern von Entitäten in meine Java-EE-basierte web-Anwendung. Hibernate als Implementierung von JPA, aber ich glaube nicht, verwenden Hibernate-spezifische features und arbeiten nur noch mit reinem JPA.
Hier einige DAO-Klasse, bemerken getOrders
Methode:
Klasse OrderDao { EntityManager em; Liste getOrders(Long customerId) { Query q = em.createQuery( "SELECT o FROM Order o WHERE o.customerId = :customerId"); q.setParameter("customerId", customerId); Rendite q.getResultList(); } }
Methode ist ziemlich einfach, aber es hat einen großen Nachteil. Jedes mal, wenn die Methode aufgerufen wird, werden folgende Aktionen durchgeführt irgendwo innerhalb der JPA-Implementierung:
- JPQL-Ausdruck geparst und kompiliert SQL.
- Entweder Statement oder PreparedStatement-Instanz erstellt und initialisiert.
- Anweisung Instanz ist gefüllt mit den Parametern und ausgeführt.
Ich glaube, dass die Schritte 1 und 2 von oben umgesetzt werden sollte, einmal pro Lebensdauer der Anwendung. Aber wie machen Sie es? In anderen Worten, ich brauche das Query-Instanzen zwischengespeichert werden.
Natürlich kann ich das implementieren eines solchen cache auf meiner Seite. Aber warten Sie, ich bin mit moderne leistungsfähige ORM ' s! Haben Sie nicht auch schon dieses, für mich?
Bemerken, dass ich nicht zu erwähnen, sowas wie Hibernate query cache die caches Ergebnis Abfragen. Hier möchte ich zur Ausführung meiner Abfragen etwas schneller.
InformationsquelleAutor der Frage Andrey | 2010-08-26
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das ist ein query plan cache in Hibernate. So HQL wird nicht analysiert, jedes mal, wenn das DAO genannt wird (also #1 wirklich nur einmal vorkommt in Ihrer Anwendung das Leben-Zeit). Es ist QueryPlanCache. Es ist nicht schwer zu dokumentieren, da es "einfach funktioniert". Aber Sie können finden Sie mehr info hier.
InformationsquelleAutor der Antwort Thierry-Dimitri Roy
Verwendung von statisch definierten benannte Abfragen. Sie sind effizienter, weil die JPA-Persistenz-provider übersetzen die JP-QL-string zum SQL-einmal beim Start der Anwendung Zeit, im Gegensatz zu jeder Zeit die Abfrage wird ausgeführt, und werden empfohlen, insbesondere für Abfragen, die Häufig ausgeführt werden.
Einer benannten Abfrage definiert, mit der
@NamedQuery
Anmerkung, die in der Regel verwendet, die auf die entity-Klasse das Ergebnis. In Ihrem Fall, auf dieOrder
Person:Ist es auch empfehlenswert Präfix benannt Abfragen mit entity-name (irgendeine Art von Namensraum und Kollisionen zu vermeiden).
Und dann in die DAO:
PS: ich wiederverwendet die Abfrage, die Sie vorgeschlagen, als Beispiel, aber es ist irgendwie seltsam, haben die
customerId
auf dieOrder
würde ich erwarten, dass einCustomer
statt.Referenzen
InformationsquelleAutor der Antwort Pascal Thivent
NamedQueries ist der Begriff, den du suchst.
InformationsquelleAutor der Antwort Chris Lercher
Was Sie wollen, ist eine NamedQuery. Auf Ihre Bestellung Entität, die Sie setzen:
Dann in die DAO-em.createNamedQuery("getOrderByCustomerId") statt Neuerstellung der Abfrage.
InformationsquelleAutor der Antwort Affe
Können Sie nicht vorbereiten Abfragen, werden nicht benannt. Das ist der Hauptgrund, Sie sollten versuchen, benannte Abfragen eher als einfache Abfragen im Quellcode.
Auch namens-Abfragen zwischengespeichert werden können, während die einfache Abfragen in java-code nicht. Natürlich ist dies ein optionales feature und aktiviert ist, verwenden Sie Hinweise auf Ihre benannte Abfrage.
InformationsquelleAutor der Antwort ichalos
JPA 2.1, Abschnitt "3.1.1 EntityManager Interface":
Die Lektion mit nach Hause nehmen aus diesem Zitat ist, dass die eingetragenen Abfrage-Typen kann nur zwischengespeichert werden, solange der entity-manager bleibt geöffnet - die wir kein Spruch für container-managed entity-Manager.
Drei Lösungen in den Sinn kommen. 1) Benannte Abfragen, wie andere haben darauf hingewiesen. 2) Cache ein
CriteriaQuery
statt und hoffentlich kann der Anbieter werfen, die in einer Art von Optimierungen aus. 3) Verwenden Sie ein application-managed entity-manager (bleibt offen).Cache ein CriteriaQuery
Verwendung eines application-managed entity manager
InformationsquelleAutor der Antwort Martin Andersson