SlideShare una empresa de Scribd logo
1 de 40
Descargar para leer sin conexión
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

Más contenido relacionado

La actualidad más candente

Redis data modeling examples
Redis data modeling examplesRedis data modeling examples
Redis data modeling examplesTerry Cho
 
AtCoder Regular Contest 045 解説
AtCoder Regular Contest 045 解説AtCoder Regular Contest 045 解説
AtCoder Regular Contest 045 解説AtCoder Inc.
 
파이썬으로 나만의 강화학습 환경 만들기
파이썬으로 나만의 강화학습 환경 만들기파이썬으로 나만의 강화학습 환경 만들기
파이썬으로 나만의 강화학습 환경 만들기정주 김
 
07 윈도우 핸들
07 윈도우 핸들07 윈도우 핸들
07 윈도우 핸들jaypi Ko
 
Voldemort : Prototype to Production
Voldemort : Prototype to ProductionVoldemort : Prototype to Production
Voldemort : Prototype to ProductionVinoth Chandar
 
정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter
정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter
정수론적 알고리즘 - Sogang ICPC Team, 2020 WinterSuhyun Park
 

La actualidad más candente (7)

Redis data modeling examples
Redis data modeling examplesRedis data modeling examples
Redis data modeling examples
 
AtCoder Regular Contest 045 解説
AtCoder Regular Contest 045 解説AtCoder Regular Contest 045 解説
AtCoder Regular Contest 045 解説
 
파이썬으로 나만의 강화학습 환경 만들기
파이썬으로 나만의 강화학습 환경 만들기파이썬으로 나만의 강화학습 환경 만들기
파이썬으로 나만의 강화학습 환경 만들기
 
Math club public
Math club publicMath club public
Math club public
 
07 윈도우 핸들
07 윈도우 핸들07 윈도우 핸들
07 윈도우 핸들
 
Voldemort : Prototype to Production
Voldemort : Prototype to ProductionVoldemort : Prototype to Production
Voldemort : Prototype to Production
 
정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter
정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter
정수론적 알고리즘 - Sogang ICPC Team, 2020 Winter
 

Similar a 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
 

Similar a Querydsl fin jug - june 2012 (20)

Querydsl overview 2014
Querydsl overview 2014Querydsl overview 2014
Querydsl overview 2014
 
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
 

Último

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure servicePooja Nehwal
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 

Último (20)

2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure serviceWhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 

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