Objektorientiertes SQL: Die Java Persistence Query Language

Die Java Persistence API Spezifikation zerfällt für den Anwender in drei große Bereiche: Die Mapping-Spezifikation für die Abbildung von Klassen auf Tabellen, das API für den Umgang mit persistenten Objekten und eine Abfragesprache zum zielgerichteten Laden größerer Objektmengen.

Der Spezifikationsgruppe hinter JPA ist mit der Abfragesprache ein kleines Meisterstück gelungen. Mit den erweiterten Möglichkeiten der Sub-Selektionen und Aggregat-Funktionen sieht die Sprache zwar aus wie SQL, funktioniert aber in sich streng objektorientiert.

Lesen Sie den vollständigen Artikel hier:
Download DatabasePro, Ausgabe 1/2009, S. 36 - 42

Errata

In diesen Artikel hat sich der Fehlerteufel eingeschlichen:

Seite 37, linke Spalte
SELECT a FROM Ausleihung
WHERE a.faelligkeitsdatum < CURRENT_DATE
SELECT a FROM Ausleihung a
WHERE a.faelligkeitsdatum < CURRENT_DATE


Seite 37, linke Spalte
SELECT a FROM Ausleihung
WHERE a.faelligkeitsdatum < CURRENT_DATE
AND a.rueckgabedatum IS NULL
SELECT a FROM Ausleihung a
WHERE a.faelligkeitsdatum < CURRENT_DATE
AND a.rueckgabedatum IS NULL


Seite 41, Kasten auf der rechten Seite
EntityManager em = ...;
QueryBuilder qb = em.getQueryBuilder();
DomainObject b = qb.createQueryDefinition( Buch.class );
List<Buch> buecher = em.createQuery(
    b
      .select()
      .where( b.get( "seiten" ).between( 350, 600 ) )
  ).getResultList();
Die Criteria-API wurde nach dem Artikel noch mehrmals umgestaltet. Der Final Draft von JPA 2.0 sieht diese Abfrage als korrekt an:

CriteriaBuilder cb = emf.getCriteriaBuilder();
CriteriaQuery<Buch> q = cb.createQuery( Buch.class );
Root<Buch> buchR = q.from( Buch.class );
q
  .select( buchR )
  .where(
    cb.between(
      buchR.<Number>get( "seiten" ), 350, 600
  ))
List<Buch> buecher = em.createQuery(q).getResultList();