Zum Inhalt springen

JPA: Abfragen

  • Verwende die Java Persistence Query Language (JPQL) für die Erstellung von Abfragen.
  • Erstelle benannte Abfragen für häufig verwendete Abfragen.
  • Definiere Named Queries in der Entitätsklasse mit @NamedQuery oder @NamedQueries.
  • Verwende die name und query Attribute für die Annotation, um die Abfrage zu definieren.
  • Referenziere die Named Query in Ihrem Repository.
@Entity
@NamedQuery(name = "User.findByEmail",
query = "SELECT u FROM User u WHERE u.email = :email")
public class User {
// ...
}
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}
  • Schreibe direkte SQL-Abfragen, anstatt JPQL zu verwenden.
  • Verwende die @Query-Annotation und setzen Sie `nativeQuery = true.
  • Füge die SQL-Abfrage als Wert für die @Query-Annotation ein.
public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "SELECT * FROM users WHERE email = :email", nativeQuery = true)
User findByEmail(String email);
}
  • Spring Data generiert automatisch Implementierungen für Abfragemethoden.
  • Definiere Methoden in Ihrem Repository-Interface gemäss den Namenskonventionen.
  • Spring Data erzeugt die Abfragen basierend auf den Methodennamen.
  • Unterstützt einfache und komplexe Abfragen, z. B. findBy, countBy, deleteBy usw.
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
List<User> findByFirstNameAndLastName(String firstName, String lastName);
List<User> findByAgeBetween(int startAge, int endAge);
}
  • Benutze CriteriaBuilder und CriteriaQuery Instanzen um komplexe Queries zu realisieren
  • Erlaubt vollständig dynamische Queries
  • Keine Plain-SQL Strings
  • Fast Typesafe Abfragen auf objektorientiertem Ansatz
public List<User> filter(String firstName, String lastName, Long jobId) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> user = cq.from(User.class);
Join<User, Job> userJob = user.join("job");
List<Predicate> predicates = new ArrayList<>();
if (firstName != null) {
predicates.add(cb.equal(user.get("firstName"), firstName));
}
if (lastName != null) {
predicates.add(cb.equal(user.get("lastName"), lastName));
}
if (searchDescription != null) {
predicates.add(cb.equal(userJob.get("id"), jobId));
}
cq.where(predicates.toArray(new Predicate[0]));
return em.createQuery(cq).getResultList();
}
  • Interface erstellen mit Methoden, die mit der Criteria API implementiert werden sollen.
  • Wir nennen das Interface <Entität>RepositoryCustom
public interface UserRepositoryCustom {
List<User> findByFirstName(String firstName);
}

Neues Custom Repository dem existierenden Repository extenden

public interface UserRepository extends CrudRepository<User, Long>, UserRepositoryCustom {
...
}
  • Das Custom Repository implementieren
  • Mit @Repository annotieren
  • Den EntityManager injecten
  • Wir nennen die Klasse <Entität>RepositoryImpl
@Repository
public class UserRepositoryImpl implements UserRepositoryCustom {
@Autowired
private EntityManager em;
@Override
public List<User> findByFirstName(String firstName) {
...
}
}

Die Methode mit der Criteria API mittels des CriteriaBuilder und der CriteriaQuery implementieren:

...
public List<User> findByFirstName(String firstName) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> cq = cb.createQuery(User.class);
Root<User> user = cq.from(User.class);
cq.where(cb.equal(user.get("firstName"), firstName));
return em.createQuery(cq).getResultList();
}
...