SlideShare une entreprise Scribd logo
1  sur  40
Télécharger pour lire hors ligne
Querydsl
Type-safe queries for Java
      Timo Westkämper
         @timowest
      www.querydsl.com
Before Querydsl

● Queries as strings within code

   TypedQuery<Person> query = em.createQuery(
      "select person from Person person " +
      "where person.firstName = ?1", Person.class);
   query.setParameter(1, "Max");
   List<Person> persons = query.getResultList();


● Must remember query syntax, domain classes,
  properties and relationships
   ●   Syntax reference always at hand
   ●   Domain model/schema reference at hand
   ●   High cognitive overhead
   ●   Error-prone
Before Querydsl

● Dynamic query building by string concatenation
  ● Very hard with multiple joins, ordering and complex
    conditionals depending on actual parameters

    StringBuilder where = new StringBuilder();
    if (firstName != null)
           where.append("person.firstName = :firstName");
    ...
    TypedQuery<Person> query = entityManager.createQuery(
           "select person from Person person where " + where,
           Person.class);
    if (firstName != null) query.setParameter("firstName", firstName);
    ...
    List<Person> persons = query.getResultList();
Before Querydsl

● Query syntax validation by execution is slow and
  breaks the flow
● Each back-end has its own query language and API
   ● SQL-like for JPA and JDO, but not for MongoDB
     and Lucene
● Verbose parameter binding by name or position to
  parameter placeholders of a prepared statement
   ● Or risk injection attack if parameters are directly
     concatenated to query
Before Querydsl

●   Hibernate Criteria API as an alternative?
    ●   Better for dynamic queries and has easier
        parameter binding, but...
    ●   Lacking expressivity, unintuitive, verbose,
        cognitive overhead for schema if not for syntax,
        not type-safe, slow validation...

●   Hibernate with three query languages to
    master with different focuses and expressivity
Querydsl

●   Domain model specific type-safe query language
    ● Compile time query validation
    ● Instant feedback on query errors
●   Compact and intuitive fluent syntax
    ● Syntactically close to SQL
    ● Great for dynamic query building


●   Supports multiple back-ends and query languages
    with consistent query API
    ● JPA/Hibernate, JDO, SQL, Lucene, Mongodb...
    ● Once you know basics of one language, you know
       basics of all SQL-like Querydsl languages
Querydsl

●   Autocomplete with Java IDEs
    ● No need to remember exact syntax
    ● No need to remember property names
●   Better support for domain model refactoring
    ● When domain changes, queries show compile
      errors
    ● Autocomplete helps fixing those
●   Developed for real-life projects, e.g. Balancion and
    Cyclos
●   Business friendly license (Apache 2.0)
Querydsl

●   Development started in 2007 with public releases since
    2008
●   Querydsl statistics:
     ● Approximately 24 000 LOC
     ● Test Code coverage about 75% (target 80%)
     ● Sonar reports
     ● FindBugs with extra annotations (@Nullable)
●   Discussions about standardisations
●   JDO/DataNucleus started with Querydsl...
Querydsl usage

●   Create your variables
    QPerson.person // default variable
    new QPerson("myPerson") // custom variable


●   Create your query
    JPAQuery, HibernateQuery, SQLQueryImpl etc


●   Populate your query
    from, where, groupBy, having, orderBy


●   Get the results
    count, iterate, list, uniqueResult
Querydsl usage

●   All expressions can be reused, immutables with
    caching – except BooleanBuilder and a few others

●   Queries, sub queries and BooleanBuilder are stateful
    builder with cascading methods
Overview of JPAQuery signature
from
    Query sources
innerJoin, join, leftJoin, fullJoin, on
    Join elements
    join(source, alias) [.on(source.prop.eq(alias.prop))]
where
   Query filters, varargs for intersection (and)
   and(), or(), allOf(), anyOf()
Overview of JPAQuery signature
groupBy
     Group by arguments in varargs form
having
     Having filter of the "group by” as an varags array of Predicate
     expressions.
orderBy
     Ordering of the result as an varargs array of order expressions.
     asc() and desc() on numeric, string and other comparable expression
limit, offset, restrict
     Paging of the result
     Limit for max results and Offset for skipping rows and
     Restrict for defining both in one call
Overview of JPAQuery signature
list
     Get the results as a typed List
listResults
     Get the results as a typed List and total row count for paging
iterate
     Get the results as a typed Iterator
count
     Get the row count as a long
uniqueResult
     Get a typed single row result
Simple example
QPerson person = QPerson.person;
JPAQuery query = new JPAQuery(entityManager);
List<Person> persons = query.from(person)
 .where(
   person.firstName.eq("John"),
   person.lastName.eq("Doe"))
 .list(person);

=>

select person from com.acme.Person person
where person.firstName eq = ?1 and person.lastName = ?2
Order
// Get persons ordered by last name and first name (desc)
query.from(person)
     .orderBy(person.lastName.asc(), person.firstName.desc())
     .list(person);

=>

select person from Person person
order by person.lastname asc, person.firstName desc
Order
// Get persons ordered by women first
query.from(person)
     .orderBy(person.gender
               .when(Gender.FEMALE).then(0)
               .otherwise(1).asc())
     .list(person);

=>

select person from Person person
order by case person.gender = Gender.FEMALE then 0 else 1 end asc
Grouping
// Get person counts grouped by last name
query.from(person)
   .groupBy(person.lastName)
   .list(person.lastName, person.count());

=>

select person.lastName, count(person) from Person person
group by person.lastName
Subqueries
//Get persons with max child count
QPerson parent = new QPerson("parent");
query.from(person)
   .where(person.children.size().eq(
       new JPASubQuery().from(parent)
                     .uniqueResult(parent.children.size().max())
    )).list(person);

=>

select person from Person person
where person.children.size() = (
  select max(parent.children.size()) from Person parent)
Constructor projection
// DTO class with @QueryProjection constructor annotation
public class PersonInfo {
   long id;
   String name;
   @QueryProjection
   public PersonInfo(long id, String name) {
     this.id = id;
     this.name = name;
   }
}


// List PersonInfo DTOs
List<PersonInfo> infos = query.from(person)
       .list(new QPersonInfo(person.id,
                  person.lastName.concat(", ”).concat(person.firstName)));
Tuple projection
// List ages of persons
List<Tuple> tuples = query.from(person)
.list(new QTuple(
    person.lastName,
    person.firstName,
    person.yearOfBirth));


for (Tuple tuple : tuples){
  // Typed access to mapped query results!
  String name = tuple.get(person.firstName) +
     " " + tuple.get(person.lastName);
  int age = tuple.get(person.yearOfBirth)
     - getCurrentYear();
  System.out.println(name + " is " + age + " years");
}
BooleanBuilder

●   Helper for building complex Boolean expressions
    dynamically

    BooleanBuilder nameDisjunction = new BooleanBuilder();
    for (String name : names) {
       nameDisjunction.or(person.firstName.like(name));
       nameDisjunction.or(person.lastName.like(name));
    }
    query.where(nameDisjunction);
Update
// Set firstName of all Does to John
long updatedRowCount =
new JPAUpdateClause(getEntityManager(), person)
   .set(person.firstName, "John")
   .where(person.lastName.eq("Doe"))
   .execute();

=>

update Person person
set person.firstName = ?1
where person.lastName = ?2
Delete
// Delete all John Does
long updatedRowCount =
new JPADeleteClause(getEntityManager(), person)
   .where(person.lastName.eq("Doe"),
      person.firstName.eq("John"))
   .execute();

=>

delete Person person
where person.lastName = ?1 and person.firstName = ?2
Querydsl extensions

●   Customize the code generation
    ● @QueryType(PropertyType.NONE)
       ● Non searchable
    ● @QueryType(PropertyType.SIMPLE)
       ● Equality comparisons only (eq, ne, in)
●   Custom query classes
    ● Extend abstract super classes and preserve fluent
      API
●   Custom expressions
    ● Static delegate methods with @QueryDelegate
    ● Template expressions for e.g. custom SQL
      functions
Querydsl extensions

●   Query serialization can be customized
    ● Works for JPA, JDO and SQL
    ● SQL dialects
    ● Overriding default templates (e.g.
      String#startsWith with like or regexp or...)
●   Expression DSL can be replaced
    ● E.g. Querydsl for Scala
●   Custom back-ends
    ● Lucene (10 classes) + Mongodb (6 classes)
Delegate methods
public class MyQueryExtensions {
  @QueryDelegate(Date.class)
  public static NumberExpression<Integer> yearAndMonth(DateTimePath<Date> date) {
     return date.year().multiply(100).add(date.month());
  }
}

=>

package ext.java.util;
...
public class QDate extends DateTimePath<java.util.Date> {
...
    public NumberExpression<Integer> yearAndMonth() {
      return MyQueryExtensions.yearAndMonth(this);
    }
}
Template expressions
// ilike
query.from(person)
.where(BooleanTemplate.create("{0} ilike {1}”,
    person.lastName, ConstantImpl.create("P%")))
.list(person);

=>

select person from Person person
where person.lastName ilike ?1
Custom query classes
public class PersonQuery extends AbstractJPAQuery<PersonQuery> {
  final QPerson person = QPerson.person;
  public PersonQuery(EntityManager em) {
     super(em);
     from(person);
  }
  public PersonQuery nameMatches(String name) {
     return where(person.firstName.like(name)
        .or(person.lastName.like(name)));
  }
}
JPA 2.0 Criteria vs Querydsl

●   JPA 2 Criteria is the standard for type-safe
    queries in JPA, but Querydsl is in our opinion
    superior in many ways
    ●   Easier and less verbose syntax
    ●   Customizable
    ●   Supports multiple back-ends – not just JPA
●   JPA has a difficult to use static query-model
    ●   Verbose property paths
    ●   Operations via builder object
●   Inverse order: “equals property value” vs.
    “property equals value”
    ●   Broken flow
Criteria example
// All possible pairs of single males and females
CriteriaQuery<Person> query = builder.createQuery(Person.class);
Root<Person> men = query.from( Person.class );
Root<Person> women = query.from( Person.class );
Predicate menRestriction = builder.and(
   builder.equal( men.get( Person_.gender ), Gender.MALE ),
   builder.equal( men.get( Person_.relationshipStatus ),
       RelationshipStatus.SINGLE )
);
Predicate womenRestriction = builder.and(
   builder.equal( women.get( Person_.gender ), Gender.FEMALE ),
   builder.equal( women.get( Person_.relationshipStatus ),
       RelationshipStatus.SINGLE )
);
query.where( builder.and( menRestriction, womenRestriction ) );
Querydsl example
// All possible pairs of single males and females
JPAQuery query = new JPAQuery(entityManager);
QPerson men = new QPerson("men");
QPerson women = new QPerson("women");
query.from(men, women).where(
       men.gender.eq(Gender.MALE),
       men.relationshipStatus.eq(RelationshipStatus.SINGLE),
       women.gender.eq(Gender.FEMALE),
       women.relationshipStatus.eq(RelationshipStatus.SINGLE));
SQL

●   Pretty similar to JPA/Hibernate
    ● No deep paths over relations though
    ● No implicit joins

     SQLTemplates templates = new MySQLTemplates();
     ...
         SQLQuery query = new SQLQueryImpl(connection,
    templates);
         query.from(person);
         query.innerJoin(parent).on(parent.id.eq(person.parent.id));

●   Shortcut for joins with foreign keys
         query.innerJoin(person.parentFK, parent);
SQL

●   Maven plugin for generating query model
●   Support for special SQL constructs and extensions

●   Databases supported include
    ●   MySQL
    ●   PostgreSQL
    ●   Oracle
    ●   MS SQL Server
    ●   H2
    ●   HSQLDB
    ●   Derby
    ●   SQLite
    ●   CUBRID
SQL extensions

●   Sub class of AbstractSQLQuery
    ● e.g. OracleQuery with connectByPrior
●   Template expressions
●   Direct addition of “flags”
    SQLInsertClause insert =
       new SQLInsertClause(connection, templates, person);
    insert.addFlag(Position.START_OVERRIDE, "replace into ");
JPA/Hibernate Maven
                 Integration
<build><plugins><plugin>
 <groupId>com.mysema.maven</groupId>
 <artifactId>maven-apt-plugin</artifactId>
 <version>1.0.3</version>
 <executions>
  <execution>
    <goals><goal>process</goal></goals>
    <configuration>
     <outputDirectory>target/generated-sources/java</outputDirectory>
     <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
    </configuration>
  </execution>
 </executions>
</plugin></plugins></build>
SQL Maven Integration
<build><plugins><plugin>
 <groupId>com.mysema.querydsl</groupId>
 <artifactId>querydsl-maven-plugin</artifactId>
 <version>${querydsl.version}</version>
 <executions><execution>
  <goals><goal>export</goal></goals>
 </execution></executions>
 <configuration>
  <jdbcDriver>org.apache.derby.jdbc.EmbeddedDriver</jdbcDriver>
  <jdbcUrl>jdbc:derby:target/demoDB;create=true</jdbcUrl>
  <!—- optional elements : namePrefix, jdbcUser, jdbcPassword, schemaPattern, tableNamePattern -->
  <packageName>com.myproject.domain</packageName>
  <targetFolder>${project.basedir}/target/generated-sources/java</targetFolder>
 </configuration>
 <dependencies><dependency>
  <!—- jdbc driver dependency -->
  <groupId>org.apache.derby</groupId>
  <artifactId>derby</artifactId>
  <version>${derby.version}</version>
 </dependency></dependencies>
</plugin></plugins></build>
What does Mysema offer for
           Querydsl?
● Free public support
  ● GitHub Issues
  ● Querydsl Google Group
  ● Mysema Blog
● Consulting services
  ● User support
  ● Custom extensions and integration
  ● Training
Querydsl support from other
            companies
●   VMware uses Querydsl in Spring Data for the
    following backends
     ● JPA
     ● SQL/JDBC
     ● MongoDB
     ● Neo4j
●   Spring Data is a good option if you want to use
    repositories in Spring with Querydsl support
Questions?
Thanks!

Timo Westkämper
   @timowest
www.querydsl.com
www.mysema.com

Contenu connexe

Tendances

gRPC on .NET Core - NDC Sydney 2019
gRPC on .NET Core - NDC Sydney 2019gRPC on .NET Core - NDC Sydney 2019
gRPC on .NET Core - NDC Sydney 2019James Newton-King
 
우아한 모노리스
우아한 모노리스우아한 모노리스
우아한 모노리스Arawn Park
 
Camel Day Italy 2021 - What's new in Camel 3
Camel Day Italy 2021 - What's new in Camel 3Camel Day Italy 2021 - What's new in Camel 3
Camel Day Italy 2021 - What's new in Camel 3Claus Ibsen
 
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 SeoulElastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 SeoulSeungYong Oh
 
[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL TuningPgDay.Seoul
 
Clean architectures with fast api pycones
Clean architectures with fast api   pyconesClean architectures with fast api   pycones
Clean architectures with fast api pyconesAlvaro Del Castillo
 
대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론
대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론
대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론Terry Cho
 
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축Youngil Cho
 
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...VMware Tanzu
 
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기PgDay.Seoul
 
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016Amazon Web Services Korea
 
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PGPgDay.Seoul
 
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdfProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdfJesmar Cannao'
 
4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴Terry Cho
 
Confluent Tech Talk Korea
Confluent Tech Talk KoreaConfluent Tech Talk Korea
Confluent Tech Talk Koreaconfluent
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]MongoDB
 
The Zen of High Performance Messaging with NATS
The Zen of High Performance Messaging with NATS The Zen of High Performance Messaging with NATS
The Zen of High Performance Messaging with NATS NATS
 

Tendances (20)

gRPC on .NET Core - NDC Sydney 2019
gRPC on .NET Core - NDC Sydney 2019gRPC on .NET Core - NDC Sydney 2019
gRPC on .NET Core - NDC Sydney 2019
 
우아한 모노리스
우아한 모노리스우아한 모노리스
우아한 모노리스
 
Camel Day Italy 2021 - What's new in Camel 3
Camel Day Italy 2021 - What's new in Camel 3Camel Day Italy 2021 - What's new in Camel 3
Camel Day Italy 2021 - What's new in Camel 3
 
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 SeoulElastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
Elastic Stack 을 이용한 게임 서비스 통합 로깅 플랫폼 - elastic{on} 2019 Seoul
 
API
APIAPI
API
 
[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning[Pgday.Seoul 2020] SQL Tuning
[Pgday.Seoul 2020] SQL Tuning
 
Clean architectures with fast api pycones
Clean architectures with fast api   pyconesClean architectures with fast api   pycones
Clean architectures with fast api pycones
 
대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론
대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론
대용량 분산 아키텍쳐 설계 #1 아키텍쳐 설계 방법론
 
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
2017 Pycon KR - Django/AWS 를 이용한 쇼핑몰 서비스 구축
 
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
The Making of the Oracle R2DBC Driver and How to Take Your Code from Synchron...
 
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
[Pgday.Seoul 2017] 8. PostgreSQL 10 새기능 소개 - 김상기
 
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
게임서비스를 위한 ElastiCache 활용 전략 :: 구승모 솔루션즈 아키텍트 :: Gaming on AWS 2016
 
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG[Pgday.Seoul 2018]  이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
[Pgday.Seoul 2018] 이기종 DB에서 PostgreSQL로의 Migration을 위한 DB2PG
 
Planning for Disaster Recovery (DR) with Galera Cluster
Planning for Disaster Recovery (DR) with Galera ClusterPlanning for Disaster Recovery (DR) with Galera Cluster
Planning for Disaster Recovery (DR) with Galera Cluster
 
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdfProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
ProxySQL and the Tricks Up Its Sleeve - Percona Live 2022.pdf
 
4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴4. 대용량 아키텍쳐 설계 패턴
4. 대용량 아키텍쳐 설계 패턴
 
Confluent Tech Talk Korea
Confluent Tech Talk KoreaConfluent Tech Talk Korea
Confluent Tech Talk Korea
 
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
Naver속도의, 속도에 의한, 속도를 위한 몽고DB (네이버 컨텐츠검색과 몽고DB) [Naver]
 
The Zen of High Performance Messaging with NATS
The Zen of High Performance Messaging with NATS The Zen of High Performance Messaging with NATS
The Zen of High Performance Messaging with NATS
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 

Similaire à Querydsl fin jug - june 2012

Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Oliver Gierke
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring DataOliver Gierke
 
Ast transformations
Ast transformationsAst transformations
Ast transformationsHamletDRC
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpaStaples
 
Hibernate
Hibernate Hibernate
Hibernate Sunil OS
 
Jpa queries
Jpa queriesJpa queries
Jpa queriesgedoplan
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackGaryCoady
 
Polyglot persistence with Spring Data
Polyglot persistence with Spring DataPolyglot persistence with Spring Data
Polyglot persistence with Spring DataCorneil du Plessis
 
Hadoop Integration in Cassandra
Hadoop Integration in CassandraHadoop Integration in Cassandra
Hadoop Integration in CassandraJairam Chandar
 
Sql Patterns
Sql PatternsSql Patterns
Sql Patternsphanleson
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceMaarten Balliauw
 
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...Leonardo De Moura Rocha Lima
 
Java Annotation Processing: A Beginner Walkthrough
Java Annotation Processing: A Beginner WalkthroughJava Annotation Processing: A Beginner Walkthrough
Java Annotation Processing: A Beginner WalkthroughMahfuz Islam Bhuiyan
 
Laurens Van Den Oever Xopus Presentation
Laurens Van Den Oever Xopus PresentationLaurens Van Den Oever Xopus Presentation
Laurens Van Den Oever Xopus PresentationAjax Experience 2009
 
NLJUG University Sessie: Java Reborn, Powered by Ordina
NLJUG University Sessie: Java Reborn, Powered by OrdinaNLJUG University Sessie: Java Reborn, Powered by Ordina
NLJUG University Sessie: Java Reborn, Powered by OrdinaMartijn Blankestijn
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaJevgeni Kabanov
 
NoSQL Endgame Percona Live Online 2020
NoSQL Endgame Percona Live Online 2020NoSQL Endgame Percona Live Online 2020
NoSQL Endgame Percona Live Online 2020Thodoris Bais
 

Similaire à Querydsl fin jug - june 2012 (20)

Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!Data access 2.0? Please welcome: Spring Data!
Data access 2.0? Please welcome: Spring Data!
 
ORM JPA
ORM JPAORM JPA
ORM JPA
 
An introduction into Spring Data
An introduction into Spring DataAn introduction into Spring Data
An introduction into Spring Data
 
Beyond java8
Beyond java8Beyond java8
Beyond java8
 
Ast transformations
Ast transformationsAst transformations
Ast transformations
 
Easy data-with-spring-data-jpa
Easy data-with-spring-data-jpaEasy data-with-spring-data-jpa
Easy data-with-spring-data-jpa
 
Hibernate
Hibernate Hibernate
Hibernate
 
Jpa queries
Jpa queriesJpa queries
Jpa queries
 
Http4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web StackHttp4s, Doobie and Circe: The Functional Web Stack
Http4s, Doobie and Circe: The Functional Web Stack
 
Polyglot persistence with Spring Data
Polyglot persistence with Spring DataPolyglot persistence with Spring Data
Polyglot persistence with Spring Data
 
Hadoop Integration in Cassandra
Hadoop Integration in CassandraHadoop Integration in Cassandra
Hadoop Integration in Cassandra
 
Sql Patterns
Sql PatternsSql Patterns
Sql Patterns
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
 
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
JavaOne 2017 - JNoSQL: The Definitive Solution for Java and NoSQL Database [C...
 
Java Annotation Processing: A Beginner Walkthrough
Java Annotation Processing: A Beginner WalkthroughJava Annotation Processing: A Beginner Walkthrough
Java Annotation Processing: A Beginner Walkthrough
 
Requery overview
Requery overviewRequery overview
Requery overview
 
Laurens Van Den Oever Xopus Presentation
Laurens Van Den Oever Xopus PresentationLaurens Van Den Oever Xopus Presentation
Laurens Van Den Oever Xopus Presentation
 
NLJUG University Sessie: Java Reborn, Powered by Ordina
NLJUG University Sessie: Java Reborn, Powered by OrdinaNLJUG University Sessie: Java Reborn, Powered by Ordina
NLJUG University Sessie: Java Reborn, Powered by Ordina
 
Embedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for JavaEmbedded Typesafe Domain Specific Languages for Java
Embedded Typesafe Domain Specific Languages for Java
 
NoSQL Endgame Percona Live Online 2020
NoSQL Endgame Percona Live Online 2020NoSQL Endgame Percona Live Online 2020
NoSQL Endgame Percona Live Online 2020
 

Dernier

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Scott Andery
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfLoriGlavin3
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rick Flair
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...panagenda
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfNeo4j
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxLoriGlavin3
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationKnoldus Inc.
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersRaghuram Pandurangan
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Alkin Tezuysal
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Hiroshi SHIBATA
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .Alan Dix
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityIES VE
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxLoriGlavin3
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 

Dernier (20)

How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
Enhancing User Experience - Exploring the Latest Features of Tallyman Axis Lo...
 
Moving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdfMoving Beyond Passwords: FIDO Paris Seminar.pdf
Moving Beyond Passwords: FIDO Paris Seminar.pdf
 
Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...Rise of the Machines: Known As Drones...
Rise of the Machines: Known As Drones...
 
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
Why device, WIFI, and ISP insights are crucial to supporting remote Microsoft...
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
Connecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdfConnecting the Dots for Information Discovery.pdf
Connecting the Dots for Information Discovery.pdf
 
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptxUse of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
Use of FIDO in the Payments and Identity Landscape: FIDO Paris Seminar.pptx
 
Data governance with Unity Catalog Presentation
Data governance with Unity Catalog PresentationData governance with Unity Catalog Presentation
Data governance with Unity Catalog Presentation
 
Generative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information DevelopersGenerative AI for Technical Writer or Information Developers
Generative AI for Technical Writer or Information Developers
 
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
Unleashing Real-time Insights with ClickHouse_ Navigating the Landscape in 20...
 
Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024Long journey of Ruby standard library at RubyConf AU 2024
Long journey of Ruby standard library at RubyConf AU 2024
 
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 
From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .From Family Reminiscence to Scholarly Archive .
From Family Reminiscence to Scholarly Archive .
 
Decarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a realityDecarbonising Buildings: Making a net-zero built environment a reality
Decarbonising Buildings: Making a net-zero built environment a reality
 
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptxThe Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
The Fit for Passkeys for Employee and Consumer Sign-ins: FIDO Paris Seminar.pptx
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 

Querydsl fin jug - june 2012

  • 1. Querydsl Type-safe queries for Java Timo Westkämper @timowest www.querydsl.com
  • 2. Before Querydsl ● Queries as strings within code TypedQuery<Person> query = em.createQuery( "select person from Person person " + "where person.firstName = ?1", Person.class); query.setParameter(1, "Max"); List<Person> persons = query.getResultList(); ● Must remember query syntax, domain classes, properties and relationships ● Syntax reference always at hand ● Domain model/schema reference at hand ● High cognitive overhead ● Error-prone
  • 3. Before Querydsl ● Dynamic query building by string concatenation ● Very hard with multiple joins, ordering and complex conditionals depending on actual parameters StringBuilder where = new StringBuilder(); if (firstName != null) where.append("person.firstName = :firstName"); ... TypedQuery<Person> query = entityManager.createQuery( "select person from Person person where " + where, Person.class); if (firstName != null) query.setParameter("firstName", firstName); ... List<Person> persons = query.getResultList();
  • 4. Before Querydsl ● Query syntax validation by execution is slow and breaks the flow ● Each back-end has its own query language and API ● SQL-like for JPA and JDO, but not for MongoDB and Lucene ● Verbose parameter binding by name or position to parameter placeholders of a prepared statement ● Or risk injection attack if parameters are directly concatenated to query
  • 5. Before Querydsl ● Hibernate Criteria API as an alternative? ● Better for dynamic queries and has easier parameter binding, but... ● Lacking expressivity, unintuitive, verbose, cognitive overhead for schema if not for syntax, not type-safe, slow validation... ● Hibernate with three query languages to master with different focuses and expressivity
  • 6. Querydsl ● Domain model specific type-safe query language ● Compile time query validation ● Instant feedback on query errors ● Compact and intuitive fluent syntax ● Syntactically close to SQL ● Great for dynamic query building ● Supports multiple back-ends and query languages with consistent query API ● JPA/Hibernate, JDO, SQL, Lucene, Mongodb... ● Once you know basics of one language, you know basics of all SQL-like Querydsl languages
  • 7. Querydsl ● Autocomplete with Java IDEs ● No need to remember exact syntax ● No need to remember property names ● Better support for domain model refactoring ● When domain changes, queries show compile errors ● Autocomplete helps fixing those ● Developed for real-life projects, e.g. Balancion and Cyclos ● Business friendly license (Apache 2.0)
  • 8. Querydsl ● Development started in 2007 with public releases since 2008 ● Querydsl statistics: ● Approximately 24 000 LOC ● Test Code coverage about 75% (target 80%) ● Sonar reports ● FindBugs with extra annotations (@Nullable) ● Discussions about standardisations ● JDO/DataNucleus started with Querydsl...
  • 9. Querydsl usage ● Create your variables QPerson.person // default variable new QPerson("myPerson") // custom variable ● Create your query JPAQuery, HibernateQuery, SQLQueryImpl etc ● Populate your query from, where, groupBy, having, orderBy ● Get the results count, iterate, list, uniqueResult
  • 10. Querydsl usage ● All expressions can be reused, immutables with caching – except BooleanBuilder and a few others ● Queries, sub queries and BooleanBuilder are stateful builder with cascading methods
  • 11. Overview of JPAQuery signature from Query sources innerJoin, join, leftJoin, fullJoin, on Join elements join(source, alias) [.on(source.prop.eq(alias.prop))] where Query filters, varargs for intersection (and) and(), or(), allOf(), anyOf()
  • 12. Overview of JPAQuery signature groupBy Group by arguments in varargs form having Having filter of the "group by” as an varags array of Predicate expressions. orderBy Ordering of the result as an varargs array of order expressions. asc() and desc() on numeric, string and other comparable expression limit, offset, restrict Paging of the result Limit for max results and Offset for skipping rows and Restrict for defining both in one call
  • 13. Overview of JPAQuery signature list Get the results as a typed List listResults Get the results as a typed List and total row count for paging iterate Get the results as a typed Iterator count Get the row count as a long uniqueResult Get a typed single row result
  • 14. Simple example QPerson person = QPerson.person; JPAQuery query = new JPAQuery(entityManager); List<Person> persons = query.from(person) .where( person.firstName.eq("John"), person.lastName.eq("Doe")) .list(person); => select person from com.acme.Person person where person.firstName eq = ?1 and person.lastName = ?2
  • 15. Order // Get persons ordered by last name and first name (desc) query.from(person) .orderBy(person.lastName.asc(), person.firstName.desc()) .list(person); => select person from Person person order by person.lastname asc, person.firstName desc
  • 16. Order // Get persons ordered by women first query.from(person) .orderBy(person.gender .when(Gender.FEMALE).then(0) .otherwise(1).asc()) .list(person); => select person from Person person order by case person.gender = Gender.FEMALE then 0 else 1 end asc
  • 17. Grouping // Get person counts grouped by last name query.from(person) .groupBy(person.lastName) .list(person.lastName, person.count()); => select person.lastName, count(person) from Person person group by person.lastName
  • 18. Subqueries //Get persons with max child count QPerson parent = new QPerson("parent"); query.from(person) .where(person.children.size().eq( new JPASubQuery().from(parent) .uniqueResult(parent.children.size().max()) )).list(person); => select person from Person person where person.children.size() = ( select max(parent.children.size()) from Person parent)
  • 19. Constructor projection // DTO class with @QueryProjection constructor annotation public class PersonInfo { long id; String name; @QueryProjection public PersonInfo(long id, String name) { this.id = id; this.name = name; } } // List PersonInfo DTOs List<PersonInfo> infos = query.from(person) .list(new QPersonInfo(person.id, person.lastName.concat(", ”).concat(person.firstName)));
  • 20. Tuple projection // List ages of persons List<Tuple> tuples = query.from(person) .list(new QTuple( person.lastName, person.firstName, person.yearOfBirth)); for (Tuple tuple : tuples){ // Typed access to mapped query results! String name = tuple.get(person.firstName) + " " + tuple.get(person.lastName); int age = tuple.get(person.yearOfBirth) - getCurrentYear(); System.out.println(name + " is " + age + " years"); }
  • 21. BooleanBuilder ● Helper for building complex Boolean expressions dynamically BooleanBuilder nameDisjunction = new BooleanBuilder(); for (String name : names) { nameDisjunction.or(person.firstName.like(name)); nameDisjunction.or(person.lastName.like(name)); } query.where(nameDisjunction);
  • 22. Update // Set firstName of all Does to John long updatedRowCount = new JPAUpdateClause(getEntityManager(), person) .set(person.firstName, "John") .where(person.lastName.eq("Doe")) .execute(); => update Person person set person.firstName = ?1 where person.lastName = ?2
  • 23. Delete // Delete all John Does long updatedRowCount = new JPADeleteClause(getEntityManager(), person) .where(person.lastName.eq("Doe"), person.firstName.eq("John")) .execute(); => delete Person person where person.lastName = ?1 and person.firstName = ?2
  • 24. Querydsl extensions ● Customize the code generation ● @QueryType(PropertyType.NONE) ● Non searchable ● @QueryType(PropertyType.SIMPLE) ● Equality comparisons only (eq, ne, in) ● Custom query classes ● Extend abstract super classes and preserve fluent API ● Custom expressions ● Static delegate methods with @QueryDelegate ● Template expressions for e.g. custom SQL functions
  • 25. Querydsl extensions ● Query serialization can be customized ● Works for JPA, JDO and SQL ● SQL dialects ● Overriding default templates (e.g. String#startsWith with like or regexp or...) ● Expression DSL can be replaced ● E.g. Querydsl for Scala ● Custom back-ends ● Lucene (10 classes) + Mongodb (6 classes)
  • 26. Delegate methods public class MyQueryExtensions { @QueryDelegate(Date.class) public static NumberExpression<Integer> yearAndMonth(DateTimePath<Date> date) { return date.year().multiply(100).add(date.month()); } } => package ext.java.util; ... public class QDate extends DateTimePath<java.util.Date> { ... public NumberExpression<Integer> yearAndMonth() { return MyQueryExtensions.yearAndMonth(this); } }
  • 27. Template expressions // ilike query.from(person) .where(BooleanTemplate.create("{0} ilike {1}”, person.lastName, ConstantImpl.create("P%"))) .list(person); => select person from Person person where person.lastName ilike ?1
  • 28. Custom query classes public class PersonQuery extends AbstractJPAQuery<PersonQuery> { final QPerson person = QPerson.person; public PersonQuery(EntityManager em) { super(em); from(person); } public PersonQuery nameMatches(String name) { return where(person.firstName.like(name) .or(person.lastName.like(name))); } }
  • 29. JPA 2.0 Criteria vs Querydsl ● JPA 2 Criteria is the standard for type-safe queries in JPA, but Querydsl is in our opinion superior in many ways ● Easier and less verbose syntax ● Customizable ● Supports multiple back-ends – not just JPA ● JPA has a difficult to use static query-model ● Verbose property paths ● Operations via builder object ● Inverse order: “equals property value” vs. “property equals value” ● Broken flow
  • 30. Criteria example // All possible pairs of single males and females CriteriaQuery<Person> query = builder.createQuery(Person.class); Root<Person> men = query.from( Person.class ); Root<Person> women = query.from( Person.class ); Predicate menRestriction = builder.and( builder.equal( men.get( Person_.gender ), Gender.MALE ), builder.equal( men.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE ) ); Predicate womenRestriction = builder.and( builder.equal( women.get( Person_.gender ), Gender.FEMALE ), builder.equal( women.get( Person_.relationshipStatus ), RelationshipStatus.SINGLE ) ); query.where( builder.and( menRestriction, womenRestriction ) );
  • 31. Querydsl example // All possible pairs of single males and females JPAQuery query = new JPAQuery(entityManager); QPerson men = new QPerson("men"); QPerson women = new QPerson("women"); query.from(men, women).where( men.gender.eq(Gender.MALE), men.relationshipStatus.eq(RelationshipStatus.SINGLE), women.gender.eq(Gender.FEMALE), women.relationshipStatus.eq(RelationshipStatus.SINGLE));
  • 32. SQL ● Pretty similar to JPA/Hibernate ● No deep paths over relations though ● No implicit joins SQLTemplates templates = new MySQLTemplates(); ... SQLQuery query = new SQLQueryImpl(connection, templates); query.from(person); query.innerJoin(parent).on(parent.id.eq(person.parent.id)); ● Shortcut for joins with foreign keys query.innerJoin(person.parentFK, parent);
  • 33. SQL ● Maven plugin for generating query model ● Support for special SQL constructs and extensions ● Databases supported include ● MySQL ● PostgreSQL ● Oracle ● MS SQL Server ● H2 ● HSQLDB ● Derby ● SQLite ● CUBRID
  • 34. SQL extensions ● Sub class of AbstractSQLQuery ● e.g. OracleQuery with connectByPrior ● Template expressions ● Direct addition of “flags” SQLInsertClause insert = new SQLInsertClause(connection, templates, person); insert.addFlag(Position.START_OVERRIDE, "replace into ");
  • 35. JPA/Hibernate Maven Integration <build><plugins><plugin> <groupId>com.mysema.maven</groupId> <artifactId>maven-apt-plugin</artifactId> <version>1.0.3</version> <executions> <execution> <goals><goal>process</goal></goals> <configuration> <outputDirectory>target/generated-sources/java</outputDirectory> <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor> </configuration> </execution> </executions> </plugin></plugins></build>
  • 36. SQL Maven Integration <build><plugins><plugin> <groupId>com.mysema.querydsl</groupId> <artifactId>querydsl-maven-plugin</artifactId> <version>${querydsl.version}</version> <executions><execution> <goals><goal>export</goal></goals> </execution></executions> <configuration> <jdbcDriver>org.apache.derby.jdbc.EmbeddedDriver</jdbcDriver> <jdbcUrl>jdbc:derby:target/demoDB;create=true</jdbcUrl> <!—- optional elements : namePrefix, jdbcUser, jdbcPassword, schemaPattern, tableNamePattern --> <packageName>com.myproject.domain</packageName> <targetFolder>${project.basedir}/target/generated-sources/java</targetFolder> </configuration> <dependencies><dependency> <!—- jdbc driver dependency --> <groupId>org.apache.derby</groupId> <artifactId>derby</artifactId> <version>${derby.version}</version> </dependency></dependencies> </plugin></plugins></build>
  • 37. What does Mysema offer for Querydsl? ● Free public support ● GitHub Issues ● Querydsl Google Group ● Mysema Blog ● Consulting services ● User support ● Custom extensions and integration ● Training
  • 38. Querydsl support from other companies ● VMware uses Querydsl in Spring Data for the following backends ● JPA ● SQL/JDBC ● MongoDB ● Neo4j ● Spring Data is a good option if you want to use repositories in Spring with Querydsl support
  • 40. Thanks! Timo Westkämper @timowest www.querydsl.com www.mysema.com