Letzte Woche habe ich darüber gesprochen, wie man eine Entität speichert. Und sobald wir eine Entität gespeichert haben, möchten wir sie auch wieder abrufen. Verglichen mit der Verwaltung bidirektionaler Verknüpfungen oder dem Speichern von Entitäten ist das Abrufen von Entitäten eigentlich recht einfach. So einfach, dass ich bezweifelt habe, ob es überhaupt Sinn macht, diesen Blog zu schreiben ;-) . Allerdings haben wir beim Schreiben des Codes dafür ein paar schöne Muster verwendet. Und ich bin gespannt, welche Muster Sie zum Abrufen von Entitäten verwenden. Hier ist also die nächste Folge der Serie über JPA-Implementierungsmuster. Grundsätzlich gibt es zwei Möglichkeiten, eine Entität mit JPA abzurufen:
- EntityManager.find findet eine Entität anhand ihrer ID oder gibt null zurück, wenn die Entität nicht existiert.
- Wenn Sie einen in Java Persistence Query Language spezifizierten Abfrage-String an EntityManager.createQuery übergeben, wird eine Abfrage Objekt zurück, das dann ausgeführt werden kann, um eine Liste von Entitäten oder eine einzelne Entität zurückzugeben.
Ein Query-Objekt kann auch durch Verweis auf eine benannte Abfrage erstellt werden (mit EntityManager.createNamedQuery), oder durch Übergabe einer SQL-Abfrage (mit einer der drei Varianten von EntityManager.createNativeQuery). Und obwohl der Name etwas anderes vermuten lässt, kann eine Abfrage auch dazu verwendet werden, eine Aktualisierungs- oder Löschanweisung auszuführen.
Eine benannte Abfrage scheint eine gute Möglichkeit zu sein, die Abfrage bei den Entitäten zu belassen, die sie abfragt, aber ich habe festgestellt, dass das nicht sehr gut funktioniert. Die meisten Abfragen benötigen Parameter, die mit einer der Varianten von
Eine einzelne Entität anhand der ID suchen und erhalten
Eine Implementierung dieses Musters für die JpaDao Basisklasse, die wir vor ein paar Blogs besprochen haben, kann wie folgt aussehen (ich habe die Find-Methode als Kontrast eingefügt):
public E findById(K id) {
return entityManager.find(entityClass, id);
}
public E getById(K id) throws EntityNotFoundException {
E entity = entityManager.find(entityClass, id);
if (Entität == null) {
throw new EntityNotFoundException(
"Entität " + entityClass.getName() + " mit id " + id + " nicht gefunden");
}
return entity;
}
Natürlich müssen Sie diese neue Methode auch in der Dao Schnittstelle hinzufügen:
E getById(K id);
Suchen und Erhalten einer einzelnen Entität mit einer Abfrage
Eine ähnliche Unterscheidung kann gemacht werden, wenn wir eine Abfrage verwenden, um nach einer einzelnen Entität zu suchen. Die
public Order findOrderSubmittedAt(Date date) throws NonUniqueResultException {
Abfrage q = entityManager.createQuery(
"SELECT e FROM " + entityClass.getName() + " e WHERE date = :date_at");
q.setParameter("date_at", date);
versuchen {
return (Bestellung) q.getSingleResult();
} catch (NoResultException exc) {
null zurückgeben;
}
}
public Order getOrderSubmittedAt(Date date) throws NoResultException, NonUniqueResultException {
Abfrage q = entityManager.createQuery(
"SELECT e FROM " + entityClass.getName() + " e WHERE date = :date_at");
q.setParameter("date_at", date);
return (Bestellung) q.getSingleResult();
}
Hinzufügen der richtigen Methoden zum OrderDao Schnittstelle hinzuzufügen, bleibt eine Übung für den Leser ;-)
Suche nach mehreren Entitäten mit einer Abfrage
Natürlich wollen wir auch in der Lage sein, mehr als eine Entität zu finden. In diesem Fall finde ich, dass es keinen nützlichen Unterschied zwischen
public List findOrdersSubmittedSince(Date date) {
Abfrage q = entityManager.createQuery(
"SELECT e FROM " + entityClass.getName() + " e WHERE date >= :date_since");
q.setParameter("date_since", date);
return (Liste) q.getResultList();
}
Aufmerksame Leser werden feststellen, dass diese Methode bereits in der ersten Version von JpaOrderDao. Während das Abrufen von Entitäten also ziemlich einfach ist, gibt es ein paar Muster, an die Sie sich bei der Implementierung von Finders und Getters halten können. Natürlich würde es mich interessieren, wie Sie dies in Ihrem Code handhaben. P.S. JPA 1.0 unterstützt dies noch nicht, aber JPA 2.0 wird eine Criteria API enthalten. Die Criteria API wird es Ihnen ermöglichen, JPA-Abfragen dynamisch zu erstellen. Criteria-Abfragen sind flexibler als String-Abfragen, so dass Sie sie abhängig von der Eingabe in einem Suchformular erstellen können. Und da Sie sie mit Hilfe von Domänenobjekten definieren, sind sie einfacher zu pflegen, da Verweise auf Domänenobjekte automatisch refaktorisiert werden. Leider verlangt die Criteria-API, dass Sie die Eigenschaften Ihrer Entität mit ihrem Namen referenzieren. Ihre IDE wird Ihnen also nicht helfen, wenn Sie diese umbenennen. Eine Liste aller Blogs zu JPA-Implementierungsmustern finden Sie in der Zusammenfassung der JPA-Implementierungsmuster.
Verfasst von
Vincent Partington
Unsere Ideen
Weitere Blogs
Contact



