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
Oliver Gierke
 
PDF
50 new features of Java EE 7 in 50 minutes
Antonio Goncalves
 
PPTX
Simplifying Persistence for Java and MongoDB with Morphia
MongoDB
 
PPTX
Spring data jpa
Jeevesh Pandey
 
PPT
Spring data presentation
Oleksii Usyk
 
PPTX
JDBC - JPA - Spring Data
Arturs Drozdovs
 
PPTX
Easy data-with-spring-data-jpa
Staples
 
PDF
Spring Data JPA from 0-100 in 60 minutes
VMware Tanzu
 
An introduction into Spring Data
Oliver Gierke
 
50 new features of Java EE 7 in 50 minutes
Antonio Goncalves
 
Simplifying Persistence for Java and MongoDB with Morphia
MongoDB
 
Spring data jpa
Jeevesh Pandey
 
Spring data presentation
Oleksii Usyk
 
JDBC - JPA - Spring Data
Arturs Drozdovs
 
Easy data-with-spring-data-jpa
Staples
 
Spring Data JPA from 0-100 in 60 minutes
VMware Tanzu
 

What's hot (20)

PPTX
Spring framework part 2
Haroon Idrees
 
PPT
Introduction to hibernate
Muhammad Zeeshan
 
PDF
Android Architecure Components - introduction
Paulina Szklarska
 
PDF
iBATIS
techmonkey4u
 
PDF
Querydsl fin jug - june 2012
Timo Westkämper
 
PPTX
Webinar: Simplifying Persistence for Java and MongoDB
MongoDB
 
PDF
Spock and Geb
Christian Baranowski
 
PDF
Introduction to Datastore
Software Park Thailand
 
PDF
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...
Cloudera, Inc.
 
PDF
Data access 2.0? Please welcome: Spring Data!
Oliver Gierke
 
PDF
Scala ActiveRecord
scalaconfjp
 
ODP
Modularized Persistence - B Zsoldos
mfrancis
 
PDF
JavaEE 8 on a diet with Payara Micro 5
Payara
 
PDF
Simple Jdbc With Spring 2.5
David Motta Baldarrago
 
DOC
Advanced Hibernate Notes
Kaniska Mandal
 
PPTX
Sqladria 2009 SRC
tepsum
 
PDF
Huahin Framework for Hadoop, Hadoop Conference Japan 2013 Winter
Ryu Kobayashi
 
PDF
Struts2 - 101
Munish Gupta
 
PDF
Zend Framework meets Doctrine 2
Mayflower GmbH
 
PDF
ZendCon2010 Doctrine MongoDB ODM
Jonathan Wage
 
Spring framework part 2
Haroon Idrees
 
Introduction to hibernate
Muhammad Zeeshan
 
Android Architecure Components - introduction
Paulina Szklarska
 
iBATIS
techmonkey4u
 
Querydsl fin jug - june 2012
Timo Westkämper
 
Webinar: Simplifying Persistence for Java and MongoDB
MongoDB
 
Spock and Geb
Christian Baranowski
 
Introduction to Datastore
Software Park Thailand
 
Cloudera Sessions - Clinic 3 - Advanced Steps - Fast-track Development for ET...
Cloudera, Inc.
 
Data access 2.0? Please welcome: Spring Data!
Oliver Gierke
 
Scala ActiveRecord
scalaconfjp
 
Modularized Persistence - B Zsoldos
mfrancis
 
JavaEE 8 on a diet with Payara Micro 5
Payara
 
Simple Jdbc With Spring 2.5
David Motta Baldarrago
 
Advanced Hibernate Notes
Kaniska Mandal
 
Sqladria 2009 SRC
tepsum
 
Huahin Framework for Hadoop, Hadoop Conference Japan 2013 Winter
Ryu Kobayashi
 
Struts2 - 101
Munish Gupta
 
Zend Framework meets Doctrine 2
Mayflower GmbH
 
ZendCon2010 Doctrine MongoDB ODM
Jonathan Wage
 
Ad

Viewers also liked (14)

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

Similar to Jpa queries (20)

PDF
JPA - Java Persistence API
Thomas Wöhlke
 
PDF
New Features of JSR 317 (JPA 2.0)
Markus Eisele
 
PDF
Understanding
Arun Gupta
 
PDF
Using the latest Java Persistence API 2.0 features
Arun Gupta
 
PDF
2014 Pre-MSc-IS-3 Persistence Layer
andreasmartin
 
PPT
YDP_API&MS_UNIT_hiii detail notes to understand api.ppt
NikhilBoda
 
PPT
YDP_API&MS_UNIT_IIIii8iiiiiiiii8iiii.ppt
NikhilBoda
 
PDF
Effiziente Datenpersistierung mit JPA 2.1 und Hibernate
Thorben Janssen
 
PPT
Java persistence api
Luis Goldster
 
PPT
Entity Persistence with JPA
Subin Sugunan
 
PDF
Using the latest Java Persistence API 2 Features - Tech Days 2010 India
Arun Gupta
 
PDF
S313431 JPA 2.0 Overview
Ludovic Champenois
 
PPTX
Hibernate Performance Tuning @JUG Thüringen
Thorben Janssen
 
ODP
Working with jpa
Ondrej Mihályi
 
PPTX
Effiziente persistierung
Thorben Janssen
 
PDF
Jpa
vantinhkhuc
 
PDF
Java Persistence API 2.0: An Overview
Sanjeeb Sahoo
 
PDF
Introduction to JPA and Hibernate including examples
ecosio GmbH
 
PDF
Naver_alternative_to_jpa
NAVER Engineering
 
PPT
JEST: REST on OpenJPA
Pinaki Poddar
 
JPA - Java Persistence API
Thomas Wöhlke
 
New Features of JSR 317 (JPA 2.0)
Markus Eisele
 
Understanding
Arun Gupta
 
Using the latest Java Persistence API 2.0 features
Arun Gupta
 
2014 Pre-MSc-IS-3 Persistence Layer
andreasmartin
 
YDP_API&MS_UNIT_hiii detail notes to understand api.ppt
NikhilBoda
 
YDP_API&MS_UNIT_IIIii8iiiiiiiii8iiii.ppt
NikhilBoda
 
Effiziente Datenpersistierung mit JPA 2.1 und Hibernate
Thorben Janssen
 
Java persistence api
Luis Goldster
 
Entity Persistence with JPA
Subin Sugunan
 
Using the latest Java Persistence API 2 Features - Tech Days 2010 India
Arun Gupta
 
S313431 JPA 2.0 Overview
Ludovic Champenois
 
Hibernate Performance Tuning @JUG Thüringen
Thorben Janssen
 
Working with jpa
Ondrej Mihályi
 
Effiziente persistierung
Thorben Janssen
 
Java Persistence API 2.0: An Overview
Sanjeeb Sahoo
 
Introduction to JPA and Hibernate including examples
ecosio GmbH
 
Naver_alternative_to_jpa
NAVER Engineering
 
JEST: REST on OpenJPA
Pinaki Poddar
 

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/  [email protected] @dirkweil Java Persistence Queries 25