SlideShare a Scribd company logo
Java Persistence Queries
Effektive DB-Abfragen mit Features aus dem Standard
und darüber hinaus
Expertenkreis Java, 18.06.2015, GEDOPLAN
Dirk Weil, GEDOPLAN GmbH
Dirk Weil
GEDOPLAN GmbH, Bielefeld
Java EE seit 1998
Konzeption und
Realisierung
Seminare
Vorträge
Veröffentlichungen
Java Persistence Queries 2
Java Persistence
Mapping OO  RDBMS
POJOs
Detachment macht DTOs verzichtbar
API zum Speichern, Laden, Löschen, Finden von DB-
Einträgen
Eclipselink, Hibernate, OpenJPA, …
Seit Java EE 5 im Standard
Auch in SE nutzbar
Aktuelle Version 2.1 3Java Persistence Queries
Demo-Entities
4Java Persistence Queries
@Entity
public class Publisher
{
@Id
private Integer id;
private String name;
@ManyToOne
private Country country;
@OneToMany(mappedBy = "publisher")
private List<Book> books;
@Entity
public class Book
{
@Id
private Integer id;
private String name;
private String isbn;
private int pages;
@ManyToOne
private Publisher publisher;
1
n
@Entity
public class Country
{
@Id
@Column(name = "ISO_CODE")
private String isoCode;
private String name;n
1
JPQL
Java Persistence Query Language
SQL-ähnlich, jedoch objektorientiert
EntityManager.createQuery liefert TypedQuery<T>
Ausführung mit getSingleResult bzw. getResultList
5Java Persistence Queries
Publisher publisher = entityManager
.createQuery("select p from Publisher p where p.name=?1",
Publisher.class)
.setParameter(1, "O'Melly Publishing")
.getSingleResult();
List<Book> books = entityManager
.createQuery("select b from Book b where b.pages>=500",
Book.class)
.getResultList();
JPQL
Navigation durch Relationen mit '.' und join
6Java Persistence Queries
List<Book> books = entityManager
.createQuery("select b from Book b where b.publisher.country=?1",
Book.class)
.setParameter(1, countryDE)
.getResultList();
List<Publisher> publishers = entityManager
.createQuery("select distinct p from Publisher p "
+ "join p.books b where b.pages>=500",
Publisher.class)
.getResultList();
JPQL
JPQL  SQL "leichtgewichtig"
7Java Persistence Queries
List<Publisher> publishers = entityManager
.createQuery("select distinct p from Publisher p "
+ "join p.books b where b.pages>=500",
Publisher.class)
.getResultList();
SELECT DISTINCT t1.ID, t1.NAME, t1.COUNTRY_ISO_CODE
FROM JPA_BOOK t0, JPA_PUBLISHER t1
WHERE ((t0.PAGES >= ?) AND (t0.PUBLISHER_ID = t1.ID))
select distinct publisher0_.ID as ID1_35_,
publisher0_.COUNTRY_ISO_CODE as COUNTRY_3_35_,
publisher0_.name as name2_35_
from JPA_PUBLISHER publisher0_
inner join JPA_BOOK books1_ on publisher0_.ID=books1_.publisher_ID
where books1_.pages>=500
Eclipselink
Hibernate
Extended Queries
Selektion von Einzelattributen etc.
8Java Persistence Queries
List<Object[]> resultList = entityManager
.createQuery("select p.name, p.country.name from Publisher p",
Object[].class)
.getResultList();
List<Object[]> resultList = entityManager
.createQuery("select p, count(b) from Publisher p "
+ "left join p.books b "
+ "group by p",
Object[].class)
.getResultList();
Extended Queries
Selektion von Einzelattributen etc.
9Java Persistence Queries
List<NameAndCount> resultList = entityManager
.createQuery("select new somepkg.NameAndCount(p.name, sum(b.pages)) "
+ "from Publisher p "
+ "join p.books b "
+ "where b.name like '%Java%' "
+ "group by p",
NameAndCount.class)
.getResultList();
public class NameAndCount
{
private String name;
private Number count;
public NameAndCount(String name, Number count)
{
Native Queries
bei schon vorhandenen SQL-Queries
für "besondere Fälle" (proprietäres SQL, spezielles Tuning, …)
"Verlust" des O/R-Mappings
auch Komplettobjekte als Ergebnis möglich
10Java Persistence Queries
@SuppressWarnings("unchecked")
List<Object[]> resultList = entityManager
.createNativeQuery("SELECT DISTINCT p.ID, p.NAME, p.COUNTRY_ISO_CODE "
+ "FROM JPA_PUBLISHER p, JPA_BOOK b "
+ "WHERE b.PUBLISHER_ID = p.ID AND b.PAGES >= ?")
.setParameter(1, 500)
.getResultList();
Stored Procedure Queries
für "noch besonderere Fälle"
IN-, OUT- oder IN/OUT-Parameter
11Java Persistence Queries
CREATE PROCEDURE GET_COCKTAIL_COUNT(IN ZUTAT_NAME VARCHAR(255))
BEGIN select count(*) from JPA_COCKTAIL C
where exists (…);
END
Number count = (Number) entityManager
.createStoredProcedureQuery("GET_COCKTAIL_COUNT")
.registerStoredProcedureParameter("ZUTAT_NAME",
String.class, ParameterMode.IN)
.setParameter("ZUTAT_NAME", "Sekt")
.getSingleResult();
Criteria Query API
Textbasierte Queries lassen sich zur Compile- oder
Deploymentzeit nicht prüfen
Syntax
Namen
Typen
12Java Persistence Queries
select p fron Publisher p
select p from Publisher
select p from Publisher p where p.nam=:name
List<Publisher> books = entityManager
.createQuery("select b from Book b where b.pages>=500",
Publisher.class)
.getResultList();
Criteria Query API
Query wird mittels API kombiniert
CriteriaQuery<T> mittels CriteriaBuilder erstellen
from, where, select …
Ausführung als "normale" TypedQuery<T>
13Java Persistence Queries
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Book> cq = cb.createQuery(Book.class);
List<Book> books = this.entityManager
.createQuery(cq)
.getResultList();
Criteria Query API
14Java Persistence Queries
// select b from Book b where b.pages>=500
Root<Book> b = cq.from(Book.class);
cq.select(b)
.where(cb.greaterThanOrEqualTo(b.get(Book_.pages), 500));
// select b from Book b where b.publisher.country=:country
Root<Book> b = cq.from(Book.class);
cq.select(b)
.where(cb.equal(b.get(Book_.publisher).get(Publisher_.country),
cb.parameter(Country.class, "country")));
List<Book> books = this.entityManager
.createQuery(cq)
.setParameter("country", CountryTest.testCountryDE)
.getResultList();
Criteria Query API
nutzt statisches Metamodell
E_ zu persistenter Klasse E
15Java Persistence Queries
@StaticMetamodel(Publisher.class)
public abstract class Publisher_
{
public static volatile SingularAttribute<GeneratedIntegerIdEntity, Integer> id;
public static volatile SingularAttribute<Publisher, String> name;
public static volatile SingularAttribute<Publisher, Country> country;
public static volatile ListAttribute<Publisher, Book> books;
@Entity
public class Publisher
{
@Id
private Integer id;
private String name;
@ManyToOne
private Country country;
@OneToMany(mappedBy = "publisher")
private List<Book> books;
Criteria Query API
Metamodell wird durch Annotation Processor generiert
muss im Compile Classpath liegen (z. B. als Maven
Dependency)
wird vom Compiler aufgerufen (Java 6+)
16Java Persistence Queries
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<version>4.3.10.Final</version>
<scope>provided</scope>
<optional>true</optional>
</dependency>
Criteria Query API
Annotation Processing in Eclipse
kann in Luna entsprechend Maven konfiguriert werden
sonst: Im Projekt Annotation Processing manuell
konfigurieren
Java Compiler
 Annotation Processing aktivieren, Zielordner wählen
 Factory Path Compile Classpath
einstellen 17Java Persistence Queries
Root<Publisher> p = cq.from(Publisher.class);
ListJoin<Publisher, Book> b = p.join(Publisher_.books);
cq.select(cb.construct(NameAndCount.class,
p.get(Publisher_.name),
cb.sum(b.get(Book_.pages))))
.where(cb.like(b.get(Book_.name), "%Java%"))
.groupBy(p);
Criteria Query API
Problem: Lesbarkeit
18Java Persistence Queries
// select new NameAndCount(p.name, sum(b.pages))
// from Publisher p
// join p.books b
// where b.name like '%Java%'
// group by p
Root<Publisher> p = cq.from(Publisher.class);
ListJoin<Publisher, Book> b = p.join(Publisher_.books);
cq.select(p.get(Publisher_.name))
.distinct(true)
.where(cb.and(cb.equal(p.get(Publisher_.country),
cb.parameter(Country.class, "country")),
cb.like(b.get(Book_.name), "%Java%")));
Criteria Query API
Problem: API durch CriteriaBuilder (u. a.) nicht "fluent"
19Java Persistence Queries
p ~ Publisher;
b ~ p.books;
c ~ Parameter(Country);
select(p.name)
.distinct()
.from(p)
.where(p.country.equal(c).and(b.name.like("%Java%")))
Wunsch
Ist
QueryDSL
Open Source (http://www.querydsl.com)
Sponsored by Mysema (http://www.mysema.com)
Query wird mittels API kombiniert
Query Roots und JPAQuery für EntityManager erzeugen
Methoden from, join, where, orderBy, distinct etc.
Query ausführen mittels singleResult, list
20Java Persistence Queries
QPublisher p = QPublisher.publisher;
JPAQuery jpaQuery = new JPAQuery(this.entityManager)
List<Publisher> result = jpaQuery.list(p);
QueryDSL
benötigt generierte Klassen
ähnlich JPA Metamodell
21Java Persistence Queries
@Generated("com.mysema.query.codegen.EntitySerializer")
public class QPublisher extends EntityPathBase<Publisher> {
public static final QPublisher publisher = new QPublisher("publisher");
public final StringPath name = createString("name");
public final ListPath<Book, QBook> books = this.<Book, QBook>createList("books", …
public final de.gedoplan.seminar.jpa.demo.basics.entity.QCountry country;
@Entity
public class Publisher
{
@Id
private Integer id;
private String name;
@ManyToOne
private Country country;
@OneToMany(mappedBy = "publisher")
private List<Book> books;
QueryDSL
Metamodell wird durch Annotation Processor generiert
z. B. mit Maven Plugin
22Java Persistence Queries
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals><goal>process</goal></goals>
<configuration>
<outputDirectory>target/generated-sources/annotations</outputDirectory>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
QueryDSL
23Java Persistence Queries
QPublisher p = QPublisher.publisher;
QBook b = QBook.book;
Param<Country> countryParam = new Param<>(Country.class);
List<String> names = new JPAQuery(this.entityManager)
.from(p)
.innerJoin(p.books, b)
.where(p.country.eq(countryParam).and(b.name.like("%Java%")))
.distinct()
.set(countryParam, CountryTest.testCountryDE)
.list(p.name);
Root<Publisher> p = cq.from(Publisher.class);
ListJoin<Publisher, Book> b = p.join(Publisher_.books);
cq.select(p.get(Publisher_.name))
.distinct(true)
.where(cb.and(cb.equal(p.get(Publisher_.country),
cb.parameter(Country.class, "country")),
cb.like(b.get(Book_.name), "%Java%")));
QueryDSL
Criteri
a
Query
API
QueryDSL
Bisherige Erfahrungen
Intuitives API (meist …)
gute Lesbarkeit
API hat noch Schwächen
z. B. Umwandlung von JPAQuery nur in Query möglich, nicht in
TypedQuery
Noch nicht ganz ausgereift
einige Bugs (z. B. Constructor Result akzeptiert keine Aggregat-
Ausdrücke)
Dokumentation lückenhaft und fehlerhaft
Umstellung com.mysema.querydsl  com.querydsl buggy
24Java Persistence Queries
More
http://www.gedoplan-it-training.de
Seminare in Berlin, Bielefeld, Inhouse
http://www.gedoplan-it-consulting.de
Reviews, Coaching, …
http://javaeeblog.wordpress.com/
http://expertenkreisjava.blogspot.de/
 dirk.weil@gedoplan.de
@dirkweil
Java Persistence Queries 25

More Related Content

PDF
An introduction into Spring Data
PDF
50 new features of Java EE 7 in 50 minutes
PPTX
Simplifying Persistence for Java and MongoDB with Morphia
PPTX
Spring data jpa
PPT
Spring data presentation
PPTX
JDBC - JPA - Spring Data
PPTX
Easy data-with-spring-data-jpa
PDF
Spring Data JPA from 0-100 in 60 minutes
An introduction into Spring Data
50 new features of Java EE 7 in 50 minutes
Simplifying Persistence for Java and MongoDB with Morphia
Spring data jpa
Spring data presentation
JDBC - JPA - Spring Data
Easy data-with-spring-data-jpa
Spring Data JPA from 0-100 in 60 minutes

What's hot (20)

PPTX
Spring framework part 2
PPT
Introduction to hibernate
PDF
Android Architecure Components - introduction
PDF
iBATIS
PDF
Querydsl fin jug - june 2012
PPTX
Webinar: Simplifying Persistence for Java and MongoDB
PDF
Spock and Geb
PDF
Introduction to Datastore
PDF
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...
PDF
Data access 2.0? Please welcome: Spring Data!
PDF
Scala ActiveRecord
ODP
Modularized Persistence - B Zsoldos
PDF
JavaEE 8 on a diet with Payara Micro 5
PDF
Simple Jdbc With Spring 2.5
DOC
Advanced Hibernate Notes
PPTX
Sqladria 2009 SRC
PDF
Huahin Framework for Hadoop, Hadoop Conference Japan 2013 Winter
PDF
Struts2 - 101
PDF
Zend Framework meets Doctrine 2
PDF
ZendCon2010 Doctrine MongoDB ODM
Spring framework part 2
Introduction to hibernate
Android Architecure Components - introduction
iBATIS
Querydsl fin jug - june 2012
Webinar: Simplifying Persistence for Java and MongoDB
Spock and Geb
Introduction to Datastore
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...
Data access 2.0? Please welcome: Spring Data!
Scala ActiveRecord
Modularized Persistence - B Zsoldos
JavaEE 8 on a diet with Payara Micro 5
Simple Jdbc With Spring 2.5
Advanced Hibernate Notes
Sqladria 2009 SRC
Huahin Framework for Hadoop, Hadoop Conference Japan 2013 Winter
Struts2 - 101
Zend Framework meets Doctrine 2
ZendCon2010 Doctrine MongoDB ODM
Ad

Viewers also liked (14)

PDF
Java EE 7 - Enterprise-Anwendungen ohne Ballast
PDF
Leichtgewichtige Microservices mit Java EE 7
PDF
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
PPTX
Apache camel
PDF
Java EE 7 - Enterprise-Anwendungen ohne Ballast
PDF
WildFly als Plattform moderner Enterprise-Anwendungen
PDF
Infinispan / JBoss Data Grid - Schneller Zugriff auf große Datenmengen im Cl...
PDF
Speeding up Java Persistence
PDF
Java Batch – Der Standard für's Stapeln
PPTX
Versionierung mit GIT
PDF
Speeding up Java Persistence
PPTX
Macit Kandemir, Flexible Datenbank-Anwendungen mit MongoDB
PDF
AngularJS
PPTX
Wie viel Client braucht das Web?JSF, Vaadin und AngularJS im Vergleich
Java EE 7 - Enterprise-Anwendungen ohne Ballast
Leichtgewichtige Microservices mit Java EE 7
javaPersistenceInActionFeaturesJenseitsDesEntryLevels
Apache camel
Java EE 7 - Enterprise-Anwendungen ohne Ballast
WildFly als Plattform moderner Enterprise-Anwendungen
Infinispan / JBoss Data Grid - Schneller Zugriff auf große Datenmengen im Cl...
Speeding up Java Persistence
Java Batch – Der Standard für's Stapeln
Versionierung mit GIT
Speeding up Java Persistence
Macit Kandemir, Flexible Datenbank-Anwendungen mit MongoDB
AngularJS
Wie viel Client braucht das Web?JSF, Vaadin und AngularJS im Vergleich
Ad

Similar to Jpa queries (20)

PDF
Dropwizard
PDF
Annotation processing and code gen
PDF
JUG Berlin Brandenburg: What's new in Java EE 7?
PPT
Slice: OpenJPA for Distributed Persistence
PDF
Spring data requery
PDF
Json generation
PDF
Java >= 9
PPTX
Spring Framework Petclinic sample application
PDF
Effiziente Datenpersistierung mit JPA 2.1 und Hibernate
PDF
Rediscovering Spring with Spring Boot(1)
ODP
From Java 6 to Java 7 reference
PPT
Hibernate
PPT
Persisting Your Objects In The Database World @ AlphaCSP Professional OSS Con...
PDF
OSGi ecosystems compared on Apache Karaf - Christian Schneider
PDF
Part 2-Support Java 17 Certif Pr Youssfi V2.pdf
PDF
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
PDF
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
PDF
Atlassian Groovy Plugins
PDF
Using the latest Java Persistence API 2 Features - Tech Days 2010 India
PDF
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
Dropwizard
Annotation processing and code gen
JUG Berlin Brandenburg: What's new in Java EE 7?
Slice: OpenJPA for Distributed Persistence
Spring data requery
Json generation
Java >= 9
Spring Framework Petclinic sample application
Effiziente Datenpersistierung mit JPA 2.1 und Hibernate
Rediscovering Spring with Spring Boot(1)
From Java 6 to Java 7 reference
Hibernate
Persisting Your Objects In The Database World @ AlphaCSP Professional OSS Con...
OSGi ecosystems compared on Apache Karaf - Christian Schneider
Part 2-Support Java 17 Certif Pr Youssfi V2.pdf
dokumen.tips_rediscovering-spring-with-spring-boot1 (1).pdf
dokumen.tips_rediscovering-spring-with-spring-boot1.pdf
Atlassian Groovy Plugins
Using the latest Java Persistence API 2 Features - Tech Days 2010 India
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...

Jpa queries

  • 1. Java Persistence Queries Effektive DB-Abfragen mit Features aus dem Standard und darüber hinaus Expertenkreis Java, 18.06.2015, GEDOPLAN Dirk Weil, GEDOPLAN GmbH
  • 2. Dirk Weil GEDOPLAN GmbH, Bielefeld Java EE seit 1998 Konzeption und Realisierung Seminare Vorträge Veröffentlichungen Java Persistence Queries 2
  • 3. Java Persistence Mapping OO  RDBMS POJOs Detachment macht DTOs verzichtbar API zum Speichern, Laden, Löschen, Finden von DB- Einträgen Eclipselink, Hibernate, OpenJPA, … Seit Java EE 5 im Standard Auch in SE nutzbar Aktuelle Version 2.1 3Java Persistence Queries
  • 4. Demo-Entities 4Java Persistence Queries @Entity public class Publisher { @Id private Integer id; private String name; @ManyToOne private Country country; @OneToMany(mappedBy = "publisher") private List<Book> books; @Entity public class Book { @Id private Integer id; private String name; private String isbn; private int pages; @ManyToOne private Publisher publisher; 1 n @Entity public class Country { @Id @Column(name = "ISO_CODE") private String isoCode; private String name;n 1
  • 5. JPQL Java Persistence Query Language SQL-ähnlich, jedoch objektorientiert EntityManager.createQuery liefert TypedQuery<T> Ausführung mit getSingleResult bzw. getResultList 5Java Persistence Queries Publisher publisher = entityManager .createQuery("select p from Publisher p where p.name=?1", Publisher.class) .setParameter(1, "O'Melly Publishing") .getSingleResult(); List<Book> books = entityManager .createQuery("select b from Book b where b.pages>=500", Book.class) .getResultList();
  • 6. JPQL Navigation durch Relationen mit '.' und join 6Java Persistence Queries List<Book> books = entityManager .createQuery("select b from Book b where b.publisher.country=?1", Book.class) .setParameter(1, countryDE) .getResultList(); List<Publisher> publishers = entityManager .createQuery("select distinct p from Publisher p " + "join p.books b where b.pages>=500", Publisher.class) .getResultList();
  • 7. JPQL JPQL  SQL "leichtgewichtig" 7Java Persistence Queries List<Publisher> publishers = entityManager .createQuery("select distinct p from Publisher p " + "join p.books b where b.pages>=500", Publisher.class) .getResultList(); SELECT DISTINCT t1.ID, t1.NAME, t1.COUNTRY_ISO_CODE FROM JPA_BOOK t0, JPA_PUBLISHER t1 WHERE ((t0.PAGES >= ?) AND (t0.PUBLISHER_ID = t1.ID)) select distinct publisher0_.ID as ID1_35_, publisher0_.COUNTRY_ISO_CODE as COUNTRY_3_35_, publisher0_.name as name2_35_ from JPA_PUBLISHER publisher0_ inner join JPA_BOOK books1_ on publisher0_.ID=books1_.publisher_ID where books1_.pages>=500 Eclipselink Hibernate
  • 8. Extended Queries Selektion von Einzelattributen etc. 8Java Persistence Queries List<Object[]> resultList = entityManager .createQuery("select p.name, p.country.name from Publisher p", Object[].class) .getResultList(); List<Object[]> resultList = entityManager .createQuery("select p, count(b) from Publisher p " + "left join p.books b " + "group by p", Object[].class) .getResultList();
  • 9. Extended Queries Selektion von Einzelattributen etc. 9Java Persistence Queries List<NameAndCount> resultList = entityManager .createQuery("select new somepkg.NameAndCount(p.name, sum(b.pages)) " + "from Publisher p " + "join p.books b " + "where b.name like '%Java%' " + "group by p", NameAndCount.class) .getResultList(); public class NameAndCount { private String name; private Number count; public NameAndCount(String name, Number count) {
  • 10. Native Queries bei schon vorhandenen SQL-Queries für "besondere Fälle" (proprietäres SQL, spezielles Tuning, …) "Verlust" des O/R-Mappings auch Komplettobjekte als Ergebnis möglich 10Java Persistence Queries @SuppressWarnings("unchecked") List<Object[]> resultList = entityManager .createNativeQuery("SELECT DISTINCT p.ID, p.NAME, p.COUNTRY_ISO_CODE " + "FROM JPA_PUBLISHER p, JPA_BOOK b " + "WHERE b.PUBLISHER_ID = p.ID AND b.PAGES >= ?") .setParameter(1, 500) .getResultList();
  • 11. Stored Procedure Queries für "noch besonderere Fälle" IN-, OUT- oder IN/OUT-Parameter 11Java Persistence Queries CREATE PROCEDURE GET_COCKTAIL_COUNT(IN ZUTAT_NAME VARCHAR(255)) BEGIN select count(*) from JPA_COCKTAIL C where exists (…); END Number count = (Number) entityManager .createStoredProcedureQuery("GET_COCKTAIL_COUNT") .registerStoredProcedureParameter("ZUTAT_NAME", String.class, ParameterMode.IN) .setParameter("ZUTAT_NAME", "Sekt") .getSingleResult();
  • 12. Criteria Query API Textbasierte Queries lassen sich zur Compile- oder Deploymentzeit nicht prüfen Syntax Namen Typen 12Java Persistence Queries select p fron Publisher p select p from Publisher select p from Publisher p where p.nam=:name List<Publisher> books = entityManager .createQuery("select b from Book b where b.pages>=500", Publisher.class) .getResultList();
  • 13. Criteria Query API Query wird mittels API kombiniert CriteriaQuery<T> mittels CriteriaBuilder erstellen from, where, select … Ausführung als "normale" TypedQuery<T> 13Java Persistence Queries CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Book> cq = cb.createQuery(Book.class); List<Book> books = this.entityManager .createQuery(cq) .getResultList();
  • 14. Criteria Query API 14Java Persistence Queries // select b from Book b where b.pages>=500 Root<Book> b = cq.from(Book.class); cq.select(b) .where(cb.greaterThanOrEqualTo(b.get(Book_.pages), 500)); // select b from Book b where b.publisher.country=:country Root<Book> b = cq.from(Book.class); cq.select(b) .where(cb.equal(b.get(Book_.publisher).get(Publisher_.country), cb.parameter(Country.class, "country"))); List<Book> books = this.entityManager .createQuery(cq) .setParameter("country", CountryTest.testCountryDE) .getResultList();
  • 15. Criteria Query API nutzt statisches Metamodell E_ zu persistenter Klasse E 15Java Persistence Queries @StaticMetamodel(Publisher.class) public abstract class Publisher_ { public static volatile SingularAttribute<GeneratedIntegerIdEntity, Integer> id; public static volatile SingularAttribute<Publisher, String> name; public static volatile SingularAttribute<Publisher, Country> country; public static volatile ListAttribute<Publisher, Book> books; @Entity public class Publisher { @Id private Integer id; private String name; @ManyToOne private Country country; @OneToMany(mappedBy = "publisher") private List<Book> books;
  • 16. Criteria Query API Metamodell wird durch Annotation Processor generiert muss im Compile Classpath liegen (z. B. als Maven Dependency) wird vom Compiler aufgerufen (Java 6+) 16Java Persistence Queries <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-jpamodelgen</artifactId> <version>4.3.10.Final</version> <scope>provided</scope> <optional>true</optional> </dependency>
  • 17. Criteria Query API Annotation Processing in Eclipse kann in Luna entsprechend Maven konfiguriert werden sonst: Im Projekt Annotation Processing manuell konfigurieren Java Compiler  Annotation Processing aktivieren, Zielordner wählen  Factory Path Compile Classpath einstellen 17Java Persistence Queries
  • 18. Root<Publisher> p = cq.from(Publisher.class); ListJoin<Publisher, Book> b = p.join(Publisher_.books); cq.select(cb.construct(NameAndCount.class, p.get(Publisher_.name), cb.sum(b.get(Book_.pages)))) .where(cb.like(b.get(Book_.name), "%Java%")) .groupBy(p); Criteria Query API Problem: Lesbarkeit 18Java Persistence Queries // select new NameAndCount(p.name, sum(b.pages)) // from Publisher p // join p.books b // where b.name like '%Java%' // group by p
  • 19. Root<Publisher> p = cq.from(Publisher.class); ListJoin<Publisher, Book> b = p.join(Publisher_.books); cq.select(p.get(Publisher_.name)) .distinct(true) .where(cb.and(cb.equal(p.get(Publisher_.country), cb.parameter(Country.class, "country")), cb.like(b.get(Book_.name), "%Java%"))); Criteria Query API Problem: API durch CriteriaBuilder (u. a.) nicht "fluent" 19Java Persistence Queries p ~ Publisher; b ~ p.books; c ~ Parameter(Country); select(p.name) .distinct() .from(p) .where(p.country.equal(c).and(b.name.like("%Java%"))) Wunsch Ist
  • 20. QueryDSL Open Source (http://www.querydsl.com) Sponsored by Mysema (http://www.mysema.com) Query wird mittels API kombiniert Query Roots und JPAQuery für EntityManager erzeugen Methoden from, join, where, orderBy, distinct etc. Query ausführen mittels singleResult, list 20Java Persistence Queries QPublisher p = QPublisher.publisher; JPAQuery jpaQuery = new JPAQuery(this.entityManager) List<Publisher> result = jpaQuery.list(p);
  • 21. QueryDSL benötigt generierte Klassen ähnlich JPA Metamodell 21Java Persistence Queries @Generated("com.mysema.query.codegen.EntitySerializer") public class QPublisher extends EntityPathBase<Publisher> { public static final QPublisher publisher = new QPublisher("publisher"); public final StringPath name = createString("name"); public final ListPath<Book, QBook> books = this.<Book, QBook>createList("books", … public final de.gedoplan.seminar.jpa.demo.basics.entity.QCountry country; @Entity public class Publisher { @Id private Integer id; private String name; @ManyToOne private Country country; @OneToMany(mappedBy = "publisher") private List<Book> books;
  • 22. QueryDSL Metamodell wird durch Annotation Processor generiert z. B. mit Maven Plugin 22Java Persistence Queries <plugin> <groupId>com.mysema.maven</groupId> <artifactId>apt-maven-plugin</artifactId> <version>1.1.3</version> <executions> <execution> <goals><goal>process</goal></goals> <configuration> <outputDirectory>target/generated-sources/annotations</outputDirectory> <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor> </configuration> </execution> </executions> </plugin>
  • 23. QueryDSL 23Java Persistence Queries QPublisher p = QPublisher.publisher; QBook b = QBook.book; Param<Country> countryParam = new Param<>(Country.class); List<String> names = new JPAQuery(this.entityManager) .from(p) .innerJoin(p.books, b) .where(p.country.eq(countryParam).and(b.name.like("%Java%"))) .distinct() .set(countryParam, CountryTest.testCountryDE) .list(p.name); Root<Publisher> p = cq.from(Publisher.class); ListJoin<Publisher, Book> b = p.join(Publisher_.books); cq.select(p.get(Publisher_.name)) .distinct(true) .where(cb.and(cb.equal(p.get(Publisher_.country), cb.parameter(Country.class, "country")), cb.like(b.get(Book_.name), "%Java%"))); QueryDSL Criteri a Query API
  • 24. QueryDSL Bisherige Erfahrungen Intuitives API (meist …) gute Lesbarkeit API hat noch Schwächen z. B. Umwandlung von JPAQuery nur in Query möglich, nicht in TypedQuery Noch nicht ganz ausgereift einige Bugs (z. B. Constructor Result akzeptiert keine Aggregat- Ausdrücke) Dokumentation lückenhaft und fehlerhaft Umstellung com.mysema.querydsl  com.querydsl buggy 24Java Persistence Queries
  • 25. More http://www.gedoplan-it-training.de Seminare in Berlin, Bielefeld, Inhouse http://www.gedoplan-it-consulting.de Reviews, Coaching, … http://javaeeblog.wordpress.com/ http://expertenkreisjava.blogspot.de/  dirk.weil@gedoplan.de @dirkweil Java Persistence Queries 25