Merge pull request #1345 from querydsl/reference-docs

Update reference docs
This commit is contained in:
Timo Westkämper 2015-05-10 20:38:36 +03:00
commit bbdfe863e1
12 changed files with 262 additions and 357 deletions

View File

@ -19,9 +19,9 @@
<programlisting language="java"><![CDATA[
QCat cat = new QCat("cat");
for (String name : query.from(cat,cats)
for (String name : queryFactory.select(cat.name).from(cat,cats)
.where(cat.kittens.size().gt(0))
.list(cat.name)) {
.fetch()) {
System.out.println(name);
}
]]></programlisting>
@ -33,9 +33,9 @@ for (String name : query.from(cat,cats)
<programlisting language="java"><![CDATA[
Cat c = alias(Cat.class, "cat");
for (String name : query.from($(c),cats)
for (String name : select($(c.getName())).from($(c),cats)
.where($(c.getKittens()).size().gt(0))
.list($(c.getName()))) {
.fetch()) {
System.out.println(name);
}
]]></programlisting>
@ -57,9 +57,9 @@ import static com.querydsl.core.alias.Alias.alias;
<programlisting language="java"><![CDATA[
Cat c = alias(Cat.class, "cat");
for (String name : query.from($(c),cats)
for (String name : queryFactory.select($(c.getName())).from($(c),cats)
.where($(c.getKittens().size()).gt(0))
.list($(c.getName()))) {
.fetch()) {
System.out.println(name);
}
]]></programlisting>

View File

@ -21,13 +21,13 @@
<programlisting language="java"><![CDATA[
public List<Customer> getCustomer(String... names) {
QCustomer customer = QCustomer.customer;
JPAQuery query = new JPAQuery(entityManager).from(customer);
JPAQuery<Customer> query = queryFactory.selectFrom(customer);
BooleanBuilder builder = new BooleanBuilder();
for (String name : names) {
builder.or(customer.name.eq(name));
}
query.where(builder); // customer.name eq name1 OR customer.name eq name2 OR ...
return query.list(customer);
return query.fetch();
}
]]></programlisting>

View File

@ -51,7 +51,7 @@
<para>
To get an impression of the expressivity of the Querydsl query and expression types go to
the javadocs and explore <code>com.querydsl.core.Query</code>, <code>com.querydsl.core.Projectable</code>
the javadocs and explore <code>com.querydsl.core.Query</code>, <code>com.querydsl.core.Fetchable</code>
and <code>com.querydsl.core.types.Expression</code>.
</para>

View File

@ -46,9 +46,9 @@ import static com.querydsl.core.alias.Alias.*;
<programlisting language="java"><![CDATA[
Cat c = alias(Cat.class, "cat");
for (String name : from($(c),cats)
for (String name : select($(c.getName())).from($(c),cats)
.where($(c.getKittens()).size().gt(0))
.list($(c.getName()))) {
.fetch()) {
System.out.println(name);
}
]]></programlisting>
@ -61,9 +61,9 @@ for (String name : from($(c),cats)
<programlisting language="java"><![CDATA[
Cat c = alias(Cat.class, "cat");
for (String name : from($(c),cats)
for (String name : select($(c.getName())).from($(c),cats)
.where($(c.getKittens().size()).gt(0))
.list($(c.getName()))) {
.fetch()) {
System.out.println(name);
}
]]></programlisting>
@ -112,9 +112,9 @@ $(c.getMate().getName().toLowerCase())
<programlisting language="java"><![CDATA[
QCat cat = new QCat("cat");
for (String name : from(cat,cats)
for (String name : select(cat.name).from(cat,cats)
.where(cat.kittens.size().gt(0))
.list(cat.name)) {
.fetch()) {
System.out.println(name);
}
]]></programlisting>

View File

@ -26,7 +26,7 @@ QUser user = QUser.user;
SearchQuery<User> query = new SearchQuery<User>(session, user);
List<User> list = query
.where(user.firstName.eq("Bob"))
.list();
.fetch();
]]></programlisting>
</sect2>

View File

@ -209,15 +209,18 @@ customer.firstName;
<title>Querying with JDO</title>
<para>
For the JDO-module JDOQuery is the main Query implementation. It
For the JDO-module <code>JDOQuery</code> is the main Query implementation. It
is instantiated like this:
</para>
<programlisting language="java"><![CDATA[
PersistenceManager pm = ...;
JDOQuery query = new JDOQuery (pm);
JDOQuery<?> query = new JDOQuery<Void>(pm);
]]></programlisting>
<para>For the examples of this chapter the queries are created via a <code>JDOQueryFactory</code> instance.
<code>JDOQueryFactory</code> should be the preferred option to obtain <code>JDOQuery</code> instances.</para>
<para>
To retrieve the customer with the first name Bob you would construct a
query like this:
@ -225,19 +228,25 @@ JDOQuery query = new JDOQuery (pm);
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
JDOQuery query = new JDOQuery (pm);
Customer bob = query.from(customer)
.where(customer.firstName.eq("Bob"))
.uniqueResult(customer);
query.close();
Customer bob = queryFactory.selectFrom(customer)
.where(customer.firstName.eq("Bob"))
.fetchOne();
]]></programlisting>
<para>
The from call defines the query source, the where part defines the
filter and uniqueResult defines the projection and tells Querydsl
to return a single element. Easy, right?
The selectFrom call defines the query source and projection, the where part defines the
filter and fetchOne tells Querydsl to return a single element. Easy, right?
</para>
<para>Alternatively you can express it also like this</para>
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
Customer bob = queryFactory.select(customer).from(customer)
.where(customer.firstName.eq("Bob"))
.fetchOne();
]]></programlisting>
<para>
To create a query with multiple sources you just use the JDOQuery class like this:
</para>
@ -253,14 +262,14 @@ query.from(customer, company);
</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.selectFrom(customer)
.where(customer.firstName.eq("Bob"), customer.lastName.eq("Wilson"));
]]></programlisting>
<para>Or like this</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.selectFrom(customer)
.where(customer.firstName.eq("Bob").and(customer.lastName.eq("Wilson")));
]]></programlisting>
@ -268,7 +277,7 @@ query.from(customer)
</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.selectFrom(customer)
.where(customer.firstName.eq("Bob").or(customer.lastName.eq("Wilson")));
]]></programlisting>
@ -280,6 +289,11 @@ query.from(customer)
<para>Use the the cascading methods of the JDOQuery class like this</para>
<para>
<emphasis>select:</emphasis>
Set the projection of the query. (Not necessary if created via query factory)
</para>
<para>
<emphasis>from:</emphasis>
Add query sources here, the first argument becomes the main source
@ -326,9 +340,9 @@ query.from(customer)
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
query.from(customer)
queryFactory.selectFrom(customer)
.orderBy(customer.lastName.asc(), customer.firstName.desc())
.list(customer);
.fetch();
]]></programlisting>
</sect2>
@ -340,9 +354,9 @@ query.from(customer)
<para>Grouping can be done in the following form</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.select(customer.lastName).from(customer)
.groupBy(customer.lastName)
.list(customer.lastName);
.fetch();
]]></programlisting>
</sect2>
@ -350,6 +364,7 @@ query.from(customer)
<sect2>
<title>Delete clauses</title>
<para>Delete clauses in Querydsl JDO follow a simple delete-where-execute form. Here
are some examples:
</para>
@ -357,9 +372,9 @@ query.from(customer)
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
// delete all customers
new JDODeleteClause(pm, customer).execute();
queryFactory.delete(customer).execute();
// delete all customers with a level less than 3
new JDODeleteClause(pm, customer).where(customer.level.lt(3)).execute();
queryFactory.delete(customer).where(customer.level.lt(3)).execute();
]]></programlisting>
<para>The second parameter of the JDODeleteClause constructor is the entity to be
@ -373,26 +388,24 @@ new JDODeleteClause(pm, customer).where(customer.level.lt(3)).execute();
<title>Subqueries</title>
<para>To create a subquery you create a <code>JDOSubQuery</code> instance, add the query parameters
via from, where etc and use unique or list to create a subquery, which is just a type-safe
expression for the query. unique is used for a unique result and list for a list result.
<para>To create a subquery you can use one of the factory methods of <code>JDOExpressions</code>
and add the query parameters via from, where etc.
</para>
<programlisting language="java"><![CDATA[
QDepartment department = QDepartment.department;
QDepartment d = new QDepartment("d");
query.from(department)
.where(department.employees.size().eq(
new JDOSubQuery().from(d).unique(AggregationFunctions.max(d.employees.size()))
)).list(department);
queryFactory.selectFrom(department)
.where(department.size.eq(JDOExpressions.select(d.size.max()).from(d))
.fetch();
]]></programlisting>
<para>represents the following native JDO query</para>
<programlisting>
SELECT this FROM com.querydsl.jdo.models.company.Department
WHERE this.employees.size() ==
(SELECT max(d.employees.size()) FROM com.querydsl.jdo.models.company.Department d)
SELECT this FROM com.querydsl.jdo.models.company.Department
WHERE this.size ==
(SELECT max(d.size) FROM com.querydsl.jdo.models.company.Department d)
</programlisting>
<para>Another example</para>
@ -400,20 +413,20 @@ query.from(department)
<programlisting language="java"><![CDATA[
QEmployee employee = QEmployee.employee;
QEmployee e = new QEmployee("e");
query.from(employee)
queryFactory.selectFrom(employee)
.where(employee.weeklyhours.gt(
new JDOSubQuery().from(employee.department.employees, e)
.where(e.manager.eq(employee.manager))
.unique(AggregationFunctions.avg(e.weeklyhours))
)).list(employee);
JDOExpressions.select(e.weeklyhours.avg())
.from(employee.department.employees, e)
.where(e.manager.eq(employee.manager)))
.fetch();
]]></programlisting>
<para>which represents the following native JDO query</para>
<programlisting>
SELECT this FROM com.querydsl.jdo.models.company.Employee
WHERE this.weeklyhours >
(SELECT avg(e.weeklyhours) FROM this.department.employees e WHERE e.manager == this.manager)
SELECT this FROM com.querydsl.jdo.models.company.Employee
WHERE this.weeklyhours >
(SELECT avg(e.weeklyhours) FROM this.department.employees e WHERE e.manager == this.manager)
</programlisting>
</sect2>
@ -477,40 +490,41 @@ SQLTemplates templates = new DerbyTemplates();
SAnimal cat = new SAnimal("cat");
SAnimal mate = new SAnimal("mate");
JDOSQLQuery query = new JDOSQLQuery(pm, templates);
List<String> names = query.from(cat).list(cat.name);
JDOSQLQuery<?> query = new JDOSQLQuery<Void>(pm, templates);
List<String> names = query.select(cat.name).from(cat).fetch();
]]></programlisting>
<para>Query multiple columns:</para>
<programlisting language="java"><![CDATA[
query = new JDOSQLQuery(pm, templates);
List<Object[]> rows = query.from(cat).list(cat.id, cat.name);
query = new JDOSQLQuery<Void>(pm, templates);
List<Tuple> rows = query.select(cat.id, cat.name).from(cat).fetch();
]]></programlisting>
<para>Query all columns:</para>
<programlisting language="java"><![CDATA[
List<Object[]> rows = query.from(cat).list(cat.all());
List<Tuple> rows = query.select(cat.all()).from(cat).fetch();
]]></programlisting>
<para>Query with joins: </para>
<programlisting language="java"><![CDATA[
query = new JDOSQLQuery(pm, templates);
cats = query.from(cat)
query = new JDOSQLQuery<Void>(pm, templates);
cats = query.select(catEntity).from(cat)
.innerJoin(mate).on(cat.mateId.eq(mate.id))
.where(cat.dtype.eq("Cat"), mate.dtype.eq("Cat"))
.list(catEntity);
.fetch();
]]></programlisting>
<para>Query and project into DTO: </para>
<programlisting language="java"><![CDATA[
query = new JDOSQLQuery(pm, templates);
List<CatDTO> catDTOs = query.from(cat)
query = new JDOSQLQuery<Void>(pm, templates);
List<CatDTO> catDTOs = query.select(Projections.constructor(CatDTO.class, cat.id, cat.name))
.from(cat)
.orderBy(cat.name.asc())
.list(Projections.constructor(CatDTO.class, cat.id, cat.name));
.fetch();
]]></programlisting>
</sect2>

View File

@ -272,7 +272,7 @@ QCustomer customer = new QCustomer("myCustomer");
<programlisting language="java"><![CDATA[
// where entityManager is a JPA EntityManager
JPAQuery query = new JPAQuery(entityManager);
JPAQuery<?> query = new JPAQuery<Void>(entityManager);
]]></programlisting>
<para>If you are using the Hibernate API instead, you can instantiate a
@ -281,11 +281,15 @@ JPAQuery query = new JPAQuery(entityManager);
<programlisting language="java"><![CDATA[
// where session is a Hibernate session
HibernateQuery query = new HibernateQuery(session);
HibernateQuery<?> query = new HibernateQuery<Void>(session);
]]></programlisting>
<para>Both <code>JPAQuery</code> and <code>HibernateQuery</code> implement the <code>JPQLQuery</code> interface.</para>
<para>Both JPAQuery and HibernateQuery implement the JPQLQuery interface.</para>
<para>For the examples of this chapter the queries are created via a <code>JPAQueryFactory</code> instance.
<code>JPAQueryFactory</code> should be the preferred option to obtain <code>JPAQuery</code> instances.</para>
<para>For the Hibernate API <code>HibernateQueryFactory</code> can be used</para>
<para>
To retrieve the customer with the first name Bob you would construct a
@ -294,16 +298,14 @@ HibernateQuery query = new HibernateQuery(session);
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
JPAQuery query = new JPAQuery(entityManager);
Customer bob = query.from(customer)
Customer bob = queryFactory.selectFrom(customer)
.where(customer.firstName.eq("Bob"))
.uniqueResult(customer);
.fetchOne();
]]></programlisting>
<para>
The from call defines the query source, the where part defines the
filter and uniqueResult defines the projection and tells Querydsl
to return a single element. Easy, right?
The selectFrom call defines the query source and projection, the where part defines the
filter and fetchOne tells Querydsl to return a single element. Easy, right?
</para>
<para>
@ -321,29 +323,29 @@ query.from(customer, company);
</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.selectFrom(customer)
.where(customer.firstName.eq("Bob"), customer.lastName.eq("Wilson"));
]]></programlisting>
<para>Or like this</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.selectFrom(customer)
.where(customer.firstName.eq("Bob").and(customer.lastName.eq("Wilson")));
]]></programlisting>
<para>In native JPQL form the query would be written like this: </para>
<programlisting>
from Customer as customer
where customer.firstName = "Bob" and customer.lastName = "Wilson"
select customer from Customer as customer
where customer.firstName = "Bob" and customer.lastName = "Wilson"
</programlisting>
<para>If you want to combine the filters via "or" then use the following pattern
</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.selectFrom(customer)
.where(customer.firstName.eq("Bob").or(customer.lastName.eq("Wilson")));
]]></programlisting>
@ -361,35 +363,35 @@ query.from(customer)
QCat cat = QCat.cat;
QCat mate = new QCat("mate");
QCate kitten = new QCat("kitten");
query.from(cat)
queryFactory.selectFrom(cat)
.innerJoin(cat.mate, mate)
.leftJoin(cat.kittens, kitten)
.list(cat);
.fetch();
]]></programlisting>
<para>The native JPQL version of the query would be </para>
<programlisting>
from Cat as cat
inner join cat.mate as mate
left outer join cat.kittens as kitten
select cat from Cat as cat
inner join cat.mate as mate
left outer join cat.kittens as kitten
</programlisting>
<para>Another example</para>
<programlisting language="java"><![CDATA[
query.from(cat)
queryFactory.selectFrom(cat)
.leftJoin(cat.kittens, kitten)
.on(kitten.bodyWeight.gt(10.0))
.list(cat);
.fetch();
]]></programlisting>
<para>With the following JPQL version</para>
<programlisting>
from Cat as cat
left join cat.kittens as kitten
on kitten.bodyWeight > 10.0
select cat from Cat as cat
left join cat.kittens as kitten
on kitten.bodyWeight > 10.0
</programlisting>
</sect2>
@ -400,6 +402,11 @@ from Cat as cat
<para>Use the the cascading methods of the JPQLQuery interface like this</para>
<para>
<emphasis>select:</emphasis>
Set the projection of the query. (Not necessary if created via query factory)
</para>
<para>
<emphasis>from:</emphasis>
Add the query sources here.
@ -452,16 +459,16 @@ from Cat as cat
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
query.from(customer)
queryFactory.selectFrom(customer)
.orderBy(customer.lastName.asc(), customer.firstName.desc())
.list(customer);
.fetch();
]]></programlisting>
<para>which is equivalent to the following native JPQL</para>
<programlisting>
from Customer as customer
order by customer.lastName asc, customer.firstName desc
select customer from Customer as customer
order by customer.lastName asc, customer.firstName desc
</programlisting>
</sect2>
@ -473,17 +480,17 @@ from Customer as customer
<para>Grouping can be done in the following form</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.select(customer.lastName).from(customer)
.groupBy(customer.lastName)
.list(customer.lastName);
.fetch();
]]></programlisting>
<para>which is equivalent to the following native JPQL</para>
<programlisting>
select customer.lastName
from Customer as customer
group by customer.lastName
from Customer as customer
group by customer.lastName
</programlisting>
@ -499,20 +506,15 @@ select customer.lastName
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
// delete all customers
new JPADeleteClause(entityManager, customer).execute();
queryFactory.delete(customer).execute();
// delete all customers with a level less than 3
new JPADeleteClause(entityManager, customer).where(customer.level.lt(3)).execute();
queryFactory.delete(customer).where(customer.level.lt(3)).execute();
]]></programlisting>
<para>The second parameter of the JPADeleteClause constructor is the entity to
be deleted.
The where call is optional and the execute call performs the deletion and returns the
amount of
deleted entities.
<para>The where call is optional and the execute call performs the deletion and returns the
amount of deleted entities.
</para>
<para>For Hibernate based Delete usage, use the HibernateDeleteClause instead.</para>
<para>DML clauses in JPA don't take JPA level cascade rules into account and don't provide
fine-grained second level cache interaction.</para>
</sect2>
@ -527,20 +529,15 @@ new JPADeleteClause(entityManager, customer).where(customer.level.lt(3)).execute
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
// rename customers named Bob to Bobby
new JPAUpdateClause(session, customer).where(customer.name.eq("Bob"))
queryFactory.update(customer).where(customer.name.eq("Bob"))
.set(customer.name, "Bobby")
.execute();
]]></programlisting>
<para>The second parameter of the JPAUpdateClause constructor is the entity to
be updated.
The set invocations define the property updates in SQL-Update-style and the execute call
performs
the Update and returns the amount of updated entities.
<para>The set invocations define the property updates in SQL-Update-style and the execute call
performs the Update and returns the amount of updated entities.
</para>
<para>For Hibernate based Update usage, use the HibernateUpdateClause instead.</para>
<para>DML clauses in JPA don't take JPA level cascade rules into account and don't provide
fine-grained second level cache interaction.</para>
@ -550,21 +547,17 @@ new JPAUpdateClause(session, customer).where(customer.name.eq("Bob"))
<title>Subqueries</title>
<para>To create a subquery you create a JPASubQuery instance, define the query
parameters
via from, where etc and use
unique or list to create a subquery, which is just a type-safe Querydsl expression for the
query.
unique is used for a unique (single) result and list for a list result.
<para>To create a subquery you use the static factory methods of <code>JPAExpressions</code> and
define the query parameters via from, where etc.
</para>
<programlisting language="java"><![CDATA[
QDepartment department = QDepartment.department;
QDepartment d = new QDepartment("d");
query.from(department)
.where(department.employees.size().eq(
new JPASubQuery().from(d).unique(d.employees.size().max())
)).list(department);
queryFactory.selectFrom(department)
.where(department.size.eq(
JPAExpressions.select(d.size.max()).from(d)))
.fetch();
]]></programlisting>
<para>Another example</para>
@ -572,16 +565,14 @@ query.from(department)
<programlisting language="java"><![CDATA[
QEmployee employee = QEmployee.employee;
QEmployee e = new QEmployee("e");
query.from(employee)
queryFactory.selectFrom(employee)
.where(employee.weeklyhours.gt(
new JPASubQuery().from(employee.department.employees, e)
.where(e.manager.eq(employee.manager))
.unique(e.weeklyhours.avg())
)).list(employee);
JPAExpressions.select(e.weeklyhours.avg())
.from(employee.department.employees, e)
.where(e.manager.eq(employee.manager))))
.fetch();
]]></programlisting>
<para>For Hibernate based sub query usage, use the HibernateSubQuery instead.</para>
</sect2>
<sect2>
@ -592,8 +583,7 @@ query.from(employee)
</para>
<programlisting language="java"><![CDATA[
JPAQuery query = new JPAQuery(entityManager);
Query jpaQuery = query.from(employee).createQuery(employee);
Query jpaQuery = queryFactory.selectFrom(employee).createQuery();
// ...
List results = jpaQuery.getResultList();
]]></programlisting>
@ -660,8 +650,8 @@ SAnimal cat = new SAnimal("cat");
SAnimal mate = new SAnimal("mate");
QCat catEntity = QCat.cat;
JPASQLQuery query = new JPASQLQuery(entityManager, templates);
List<String> names = query.from(cat).list(cat.name);
JPASQLQuery<?> query = new JPASQLQuery<Void>(entityManager, templates);
List<String> names = query.select(cat.name).from(cat).fetch();
]]></programlisting>
<para>If you mix entity (e.g. QCat) and table (e.g. SAnimal) references in your query you need to make sure that they
@ -678,44 +668,45 @@ SAnimal cat = new SAnimal(catEntity.getMetadata().getName());
<para>Query multiple columns:</para>
<programlisting language="java"><![CDATA[
query = new JPASQLQuery(entityManager, templates);
List<Object[]> rows = query.from(cat).list(cat.id, cat.name);
query = new JPASQLQuery<Void>(entityManager, templates);
List<Tuple> rows = query.select(cat.id, cat.name).from(cat).fetch();
]]></programlisting>
<para>Query all columns:</para>
<programlisting language="java"><![CDATA[
List<Object[]> rows = query.from(cat).list(cat.all());
List<Tuple> rows = query.select(cat.all()).from(cat).fetch();
]]></programlisting>
<para>Query in SQL, but project as entity: </para>
<programlisting language="java"><![CDATA[
query = new JPASQLQuery(entityManager, templates);
List<Cat> cats = query.from(cat).orderBy(cat.name.asc()).list(catEntity);
query = new JPASQLQuery<Void>(entityManager, templates);
List<Cat> cats = query.select(catEntity).from(cat).orderBy(cat.name.asc()).fetch();
]]></programlisting>
<para>Query with joins: </para>
<programlisting language="java"><![CDATA[
query = new JPASQLQuery(entityManager, templates);
cats = query.from(cat)
query = new JPASQLQuery<Void>(entityManager, templates);
cats = query.select(catEntity).from(cat)
.innerJoin(mate).on(cat.mateId.eq(mate.id))
.where(cat.dtype.eq("Cat"), mate.dtype.eq("Cat"))
.list(catEntity);
.fetch();
]]></programlisting>
<para>Query and project into DTO: </para>
<programlisting language="java"><![CDATA[
query = new JPASQLQuery(entityManager, templates);
List<CatDTO> catDTOs = query.from(cat)
query = new JPASQLQuery<Void>(entityManager, templates);
List<CatDTO> catDTOs = query.select(Projections.constructor(CatDTO.class, cat.id, cat.name))
.from(cat)
.orderBy(cat.name.asc())
.list(Projections.constructor(CatDTO.class, cat.id, cat.name));
.fetch();
]]></programlisting>
<para>If you are using the Hibernate API instead of the JPA API, then use
HibernateSQLQuery instead.
<code>HibernateSQLQuery</code> instead.
</para>
</sect2>

View File

@ -88,7 +88,7 @@ IndexSearcher searcher = new IndexSearcher(index);
LuceneQuery query = new LuceneQuery(true, searcher);
List<Document> documents = query
.where(doc.year.between("1800", "2000").and(doc.title.startsWith("Huckle"))
.list();
.fetch();
]]></programlisting>
<para>which is transformed into the following Lucene query:</para>
@ -147,7 +147,7 @@ List<Document> documents = query
query
.where(doc.title.like("*"))
.orderBy(doc.title.asc(), doc.year.desc())
.list();
.fetch();
]]></programlisting>
<para>which is equivalent to the following Lucene query</para>
@ -167,7 +167,7 @@ Sort sort = ...;
query
.where(doc.title.like("*"))
.sort(sort)
.list();
.fetch();
]]></programlisting>
</sect2>
@ -181,7 +181,7 @@ query
query
.where(doc.title.like("*"))
.limit(10)
.list();
.fetch();
]]></programlisting>
</sect2>
@ -195,7 +195,7 @@ query
query
.where(doc.title.like("*"))
.offset(3)
.list();
.fetch();
]]></programlisting>
</sect2>
@ -211,7 +211,7 @@ query
<programlisting language="java"><![CDATA[
query
.where(LuceneExpressions.fuzzyLike(doc.title, "Hello"))
.list();
.fetch();
]]></programlisting>
</sect2>
@ -226,7 +226,7 @@ query
query
.where(doc.title.like("*"))
.filter(filter)
.list();
.fetch();
]]></programlisting>
<para>A shortcut for distinct filtering is provided via the distinct(Path) method:
@ -236,7 +236,7 @@ query
query
.where(doc.title.like("*"))
.distinct(doc.title)
.list();
.fetch();
]]></programlisting>
</sect2>

View File

@ -104,7 +104,7 @@ QUser user = new QUser("user");
MorphiaQuery<User> query = new MorphiaQuery<User>(morphia, datastore, user);
List<User> list = query
.where(user.firstName.eq("Bob"))
.list();
.fetch();
]]></programlisting>
</sect2>
@ -157,7 +157,7 @@ List<User> list = query
query
.where(doc.title.like("*"))
.orderBy(doc.title.asc(), doc.year.desc())
.list();
.fetch();
]]></programlisting>
<para>The results are sorted ascending based on title and year.</para>
@ -173,7 +173,7 @@ query
query
.where(doc.title.like("*"))
.limit(10)
.list();
.fetch();
]]></programlisting>
</sect2>
@ -187,7 +187,7 @@ query
query
.where(doc.title.like("*"))
.offset(3)
.list();
.fetch();
]]></programlisting>
</sect2>
@ -203,7 +203,7 @@ query
<programlisting language="java"><![CDATA[
query
.where(geoEntity.location.near(50.0, 50.0))
.list();
.fetch();
]]></programlisting>
</sect2>
@ -213,13 +213,13 @@ query
<title>Select only relevant fields</title>
<para>To select only relevant fields you can use the overloaded projection methods
list, iterate, uniqueResult and singleResult methods like this
fetch, iterate, fetchOne and fetchFirst methods like this
</para>
<programlisting language="java"><![CDATA[
query
.where(doc.title.like("*"))
.list(doc.title, doc.path);
.fetch(doc.title, doc.path);
]]></programlisting>
<para>This query will load only the title and path fields of the documents.</para>

View File

@ -67,49 +67,6 @@ map.get("X") map("X")
</sect2>
<sect2>
<title>Improved projections</title>
<para>The Querydsl Scala module offers a few implicit conversion to make Querydsl
query projections more Scala compatible.
</para>
<para>
The <code>RichProjectable</code> and <code>RichSimpleProjectable</code> wrappers should be used to enable
Scala projections for Querydsl queries.
By importing the contents of <code>com.querydsl.scala.Helpers</code>
the needed implicit conversions become available.
</para>
<para>
For example the following query with the standard API would return a <code>java.util.List</code> of
type <code>Object[]</code>.
</para>
<programlisting language="java"><![CDATA[
query.from(person).list(person.firstName, person.lastName, person.age)
]]></programlisting>
<para>With the added conversions you can use select instead of list for Scala list
typed results, unique instead of uniqueResult for
Option typed results and single instead of singleResult for Option typed results.
</para>
<para>The previous query could be expressed like this with the implicit conversions:
</para>
<programlisting language="java"><![CDATA[
import com.querydsl.scala.Helpers._
query.from(person).select(person.firstName, person.lastName, person.age)
]]></programlisting>
<para>In this case the result type would be List[(String,String,Integer)] or in other
words List of Tuple3[String,String,Integer].
</para>
</sect2>
<sect2>
<title>Querying with SQL</title>
@ -152,54 +109,6 @@ exporter.setTypeMappings(ScalaTypeMappings.create)
exporter.export(connection.getMetaData)
]]></programlisting>
<sect3>
<title>Compact queries</title>
<para>Querydsl Scala provides a compact query syntax for Querydsl SQL. The syntax is
inspired by domain oriented query syntaxes like that from the Rogue framework.
</para>
<para>
The domain oriented queries are implemented as implicit conversions from
<code>RelationalPath</code> instances into queries. This functionality
can be made available by implementing the
<code>com.querydsl.scala.sql.SQLHelpers</code>
trait in your service or DAO classes.
</para>
<para>Using this compact syntax you can use your meta model classes as a starting
point for queries.
</para>
<para>Instead of the following normal syntax</para>
<programlisting language="java"><![CDATA[
query().from(employee).select(employee.firstName, employee.lastName)
]]></programlisting>
<para>you could use the companion object of Employee or QEmployee and write it like
this </para>
<programlisting language="java"><![CDATA[
Employee.select(_.firstName, _.lastName)
]]></programlisting>
<para>Instead of giving expressions to orderBy, where, select, single and unique you
can give functions which take the root expression of
the query and return another expression. The expanded form of the previous example would be
</para>
<programlisting language="java"><![CDATA[
Employee.select({ e => e.firstName }, { e => e.lastName })
]]></programlisting>
<para>
See the signature of the <code>com.querydsl.scala.sql.RichSimpleQuery</code>
class for details.
</para>
</sect3>
<sect3>
@ -297,35 +206,35 @@ class Department {
<programlisting language="java"><![CDATA[
val person = Person as "person"
query.from(person).where(person.firstName like "Rob%").list(person)
selectFrom(person).where(person.firstName like "Rob%").fetch()
]]></programlisting>
<para>Unique result</para>
<programlisting language="java"><![CDATA[
query.from(person).where(person.firstName like "Rob%").unique(person)
selectFrom(person).where(person.firstName like "Rob%").fetchOne()
]]></programlisting>
<para>Long where</para>
<programlisting language="java"><![CDATA[
query.from(person)
selectFrom(person)
.where(person.firstName like "Rob%", person.lastName like "An%")
.list(person)
.fetch()
]]></programlisting>
<para>Order</para>
<programlisting language="java"><![CDATA[
query.from(person).orderBy(person.firstName asc).list(person)
selectFrom(person).orderBy(person.firstName asc).fetch()
]]></programlisting>
<para>Not null</para>
<programlisting language="java"><![CDATA[
query.from(person)
selectFrom(person)
.where(person.firstName isEmpty, person.lastName isNotNull)
.list(person)
.fetch()
]]></programlisting>
<para>The factory method for query creation is</para>

View File

@ -147,7 +147,7 @@ query.where(table.geo.contains(point));
<title>Intersection</title>
<programlisting language="java"><![CDATA[
Geometry geo = query.uniqueResult(table.geo1.intersection(table.geo2));
Geometry geo = query.select(table.geo1.intersection(table.geo2)).fetchOne();
]]></programlisting>
</sect3>
@ -161,7 +161,7 @@ Geometry geo = query.uniqueResult(table.geo1.intersection(table.geo2));
<programlisting language="java"><![CDATA[
QSpatialRefSys spatialRefSys = QSpatialRefSys.spatialRefSys;
List<SpatialRefSys> referenceSystems = query.from(spatialRefSys).list(spatialRefSys);
List<SpatialRefSys> referenceSystems = query.select(spatialRefSys).from(spatialRefSys).fetch();
]]></programlisting>
</sect3>

View File

@ -278,7 +278,6 @@
</typeMappings>
]]></programlisting>
<para>The defaults for the numeric mappings are </para>
<table>
@ -481,15 +480,21 @@ Configuration configuration = new Configuration(templates);
<title>Querying</title>
<para>For the following examples we will be using the <code>SQLQueryFactory</code> class for query creation.
Using it results in more concise code compared to constructor based query creation.</para>
<programlisting language="java"><![CDATA[
SQLQueryFactory queryFactory = new SQLQueryFactory(configuration, dataSource);
]]></programlisting>
<para>Querying with Querydsl SQL is as simple as this:</para>
<programlisting language="java"><![CDATA[
QCustomer customer = new QCustomer("c");
SQLQuery query = new SQLQuery(connection, configuration);
List<String> lastNames = query.from(customer)
List<String> lastNames = queryFactory.select(customer.lastName).from(customer)
.where(customer.firstName.eq("Bob"))
.list(customer.lastName);
.fetch();
]]></programlisting>
<para>
@ -513,6 +518,11 @@ WHERE c.first_name = 'Bob'
<para>Use the the cascading methods of the SQLQuery class like this</para>
<para>
<emphasis>select:</emphasis>
Set the projection of the query. (Not necessary if created via query factory)
</para>
<para>
<emphasis>from:</emphasis>
Add the query sources here.
@ -566,25 +576,28 @@ WHERE c.first_name = 'Bob'
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
QCompany company = QCompany.company;
query.from(customer)
queryFactory.select(customer.firstName, customer.lastName, company.name)
.from(customer)
.innerJoin(customer.company, company)
.list(customer.firstName, customer.lastName, company.name);
.fetch();
]]></programlisting>
<para>and for a left join:</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.select(customer.firstName, customer.lastName, company.name)
.from(customer)
.leftJoin(customer.company, company)
.list(customer.firstName, customer.lastName, company.name);
.fetch();
]]></programlisting>
<para>Alternatively the join condition can also be written out:</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.select(customer.firstName, customer.lastName, company.name)
.from(customer)
.leftJoin(company).on(customer.company.eq(company.id))
.list(customer.firstName, customer.lastName, company.name);
.fetch();
]]></programlisting>
</sect2>
@ -597,9 +610,10 @@ query.from(customer)
<para>The syntax for declaring ordering is </para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.select(customer.firstName, customer.lastName)
.from(customer)
.orderBy(customer.lastName.asc(), customer.firstName.asc())
.list(customer.firstName, customer.lastName);
.fetch();
]]></programlisting>
<para>which is equivalent to the following native SQL</para>
@ -619,9 +633,10 @@ ORDER BY c.last_name ASC, c.first_name ASC
<para>Grouping can be done in the following form</para>
<programlisting language="java"><![CDATA[
query.from(customer)
queryFactory.select(customer.lastName)
.from(customer)
.groupBy(customer.lastName)
.list(customer.lastName);
.fetch();
]]></programlisting>
<para>which is equivalent to the following native SQL</para>
@ -640,28 +655,29 @@ GROUP BY c.last_name
<title>Using Subqueries</title>
<para>
To create a subquery you create a SQLSubQuery instance, define the query parameters via
from, where etc and use unique or list to create a subquery, which is just a type-safe Querydsl
expression for the query. unique is used for a unique (single) result and list for a
list result.
<para>To create a subquery you can use one of the factory methods of <code>SQLExpressions</code>
and add the query parameters via from, where etc.
</para>
<programlisting language="java"><![CDATA[
QCustomer customer = QCustomer.customer;
QCustomer customer2 = new QCustomer("customer2");
query.from(customer).where(
customer.status.eq(new SQLSubQuery().from(customer2).unique(customer2.status.max()))
.list(customer.all())
queryFactory.select(customer.all())
.from(customer)
.where(customer.status.eq(
SQLExpressions.select(customer2.status.max()).from(customer2)))
.fetch()
]]></programlisting>
<para>Another example</para>
<programlisting language="java"><![CDATA[
QStatus status = QStatus.status;
query.from(customer).where(
customer.status.in(new SQLSubQuery().from(status).where(status.level.lt(3)).list(status.id))
.list(customer.all())
queryFactory.select(customer.all())
.from(customer)
.where(customer.status.in(
SQLExpressions.select(status.id).from(status).where(status.level.lt(3))))
.fetch();
]]></programlisting>
</sect2>
@ -673,8 +689,8 @@ query.from(customer).where(
<para>To select literals you need to create constant instances for them like this:</para>
<programlisting language="java"><![CDATA[
query.list(Expressions.constant(1),
Expressions.constant("abc"));
queryFactory.select(Expressions.constant(1),
Expressions.constant("abc"));
]]></programlisting>
<para>The class <code>com.querydsl.core.types.dsl.Expressions</code> offers also other useful static methods for
@ -692,7 +708,7 @@ query.list(Expressions.constant(1),
</para>
<programlisting language="java"><![CDATA[
public class MySQLQuery extends AbstractSQLQuery<MySQLQuery> {
public class MySQLQuery<T> extends AbstractSQLQuery<T, MySQLQuery<T>> {
public MySQLQuery(Connection conn) {
this(conn, new MySQLTemplates(), new DefaultQueryMetadata());
@ -736,11 +752,11 @@ public class MySQLQuery extends AbstractSQLQuery<MySQLQuery> {
<para>Usage example:</para>
<programlisting language="java"><![CDATA[
query.from(employee)
.list(SQLExpressions.rowNumber()
queryFactory.select(SQLExpressions.rowNumber()
.over()
.partitionBy(employee.name)
.orderBy(employee.id));
.orderBy(employee.id))
.from(employee)
]]></programlisting>
</sect2>
@ -753,17 +769,21 @@ query.from(employee)
<programlisting language="java"><![CDATA[
QEmployee employee = QEmployee.employee;
query.with(employee, sq().from(employee).where(employee.name.startsWith("A")).list(employee.all()))
.from(...)
queryFactory.with(employee, SQLExpressions.select(employee.all)
.from(employee)
.where(employee.name.startsWith("A")))
.from(...)
]]></programlisting>
<para>And using a column listing</para>
<programlisting language="java"><![CDATA[
QEmployee employee = QEmployee.employee;
query.with(employee, employee.id, employee.name)
.as(sq().from(employee).where(employee.name.startsWith("A")).list(employee.id, employee.name))
.from(...)
queryFactory.with(employee, employee.id, employee.name)
.as(SQLExpressions.select(employee.id, employee.name)
.from(employee)
.where(employee.name.startsWith("A")))
.from(...)
]]></programlisting>
<para>If the columns of the common table expression are a subset of an existing table or view
@ -776,10 +796,11 @@ query.with(employee, employee.id, employee.name)
QEmployee employee = QEmployee.employee;
QDepartment department = QDepartment.department;
PathBuilder<Tuple> emp = new PathBuilder<Tuple>(Tuple.class, "emp");
query.with(emp, sq().from(employee).innerJoin(department).on(employee.departmentId.eq(department.id))
.list(employee.id, employee.name, employee.departmentId,
department.name.as("departmentName")))
.from(...)
queryFactory.with(emp, SQLExpressions.select(employee.id, employee.name, employee.departmentId,
department.name.as("departmentName"))
.from(employee)
.innerJoin(department).on(employee.departmentId.eq(department.id))))
.from(...)
]]></programlisting>
</sect2>
@ -798,11 +819,6 @@ query.with(emp, sq().from(employee).innerJoin(department).on(employee.department
<title>Using Data manipulation commands</title>
<para>All the DMLClause implementation in the Querydsl SQL module take three
parameters, the Connection, the SQLTemplates instance
used in the queries and the main entity the DMLClause is bound to.
</para>
<sect3>
<title>Insert</title>
@ -812,7 +828,7 @@ query.with(emp, sq().from(employee).innerJoin(department).on(employee.department
<programlisting language="java"><![CDATA[
QSurvey survey = QSurvey.survey;
new SQLInsertClause(conn, configuration, survey)
queryFactory.insert(survey)
.columns(survey.id, survey.name)
.values(3, "Hello").execute();
]]></programlisting>
@ -820,24 +836,24 @@ new SQLInsertClause(conn, configuration, survey)
<para>Without columns</para>
<programlisting language="java"><![CDATA[
new SQLInsertClause(conn, configuration, survey)
queryFactory.insert(survey)
.values(4, "Hello").execute();
]]></programlisting>
<para>With subquery</para>
<programlisting language="java"><![CDATA[
new SQLInsertClause(conn, configuration, survey)
queryFactory.insert(survey)
.columns(survey.id, survey.name)
.select(new SQLSubQuery().from(survey2).list(survey2.id.add(1), survey2.name))
.select(SQLExpressions.select(survey2.id.add(1), survey2.name).from(survey2))
.execute();
]]></programlisting>
<para>With subquery, without columns</para>
<programlisting language="java"><![CDATA[
new SQLInsertClause(conn, configuration, survey)
.select(new SQLSubQuery().from(survey2).list(survey2.id.add(10), survey2.name))
queryFactory.insert(survey)
.select(SQLExpressions.select(survey2.id.add(10), survey2.name).from(survey2))
.execute();
]]></programlisting>
@ -847,7 +863,7 @@ new SQLInsertClause(conn, configuration, survey)
<programlisting language="java"><![CDATA[
QSurvey survey = QSurvey.survey;
new SQLInsertClause(conn, configuration, survey)
queryFactory.insert(survey)
.set(survey.id, 3)
.set(survey.name, "Hello").execute();
]]></programlisting>
@ -874,14 +890,14 @@ set(...)
<para>To populate a clause instance based on the contents of a bean you can use</para>
<programlisting language="java"><![CDATA[
new SQLInsertClause(conn, configuration, survey)
queryFactory.insert(survey)
.populate(surveyBean).execute();
]]></programlisting>
<para>This will exclude null bindings, if you need also null bindings use</para>
<programlisting language="java"><![CDATA[
new SQLInsertClause(conn, configuration, survey)
queryFactory.insert(survey)
.populate(surveyBean, DefaultMapper.WITH_NULL_BINDINGS).execute();
]]></programlisting>
@ -896,7 +912,7 @@ new SQLInsertClause(conn, configuration, survey)
<programlisting language="java"><![CDATA[
QSurvey survey = QSurvey.survey;
new SQLUpdateClause(conn, configuration, survey)
queryFactory.update(survey)
.where(survey.name.eq("XXX"))
.set(survey.name, "S")
.execute();
@ -905,7 +921,7 @@ new SQLUpdateClause(conn, configuration, survey)
<para>Without where</para>
<programlisting language="java"><![CDATA[
new SQLUpdateClause(conn, configuration, survey)
queryFactory.update(survey)
.set(survey.name, "S")
.execute();
]]></programlisting>
@ -913,7 +929,7 @@ new SQLUpdateClause(conn, configuration, survey)
<para>Using bean population</para>
<programlisting language="java"><![CDATA[
new SQLUpdateClause(conn, configuration, survey)
queryFactory.update(survey)
.populate(surveyBean)
.execute();
]]></programlisting>
@ -929,7 +945,7 @@ new SQLUpdateClause(conn, configuration, survey)
<programlisting language="java"><![CDATA[
QSurvey survey = QSurvey.survey;
new SQLDeleteClause(conn, configuration, survey)
queryFactory.delete(survey)
.where(survey.name.eq("XXX"))
.execute();
@ -938,7 +954,7 @@ new SQLDeleteClause(conn, configuration, survey)
<para>Without where</para>
<programlisting language="java"><![CDATA[
new SQLDeleteClause(conn, configuration, survey)
queryFactory.delete(survey)
.execute()
]]></programlisting>
@ -961,10 +977,10 @@ new SQLDeleteClause(conn, configuration, survey)
<programlisting language="java"><![CDATA[
QSurvey survey = QSurvey.survey;
insert(survey).values(2, "A").execute();
insert(survey).values(3, "B").execute();
queryFactory.insert(survey).values(2, "A").execute();
queryFactory.insert(survey).values(3, "B").execute();
SQLUpdateClause update = update(survey);
SQLUpdateClause update = queryFactory.update(survey);
update.set(survey.name, "AA").where(survey.name.eq("A")).addBatch();
update.set(survey.name, "BB").where(survey.name.eq("B")).addBatch();
]]></programlisting>
@ -972,10 +988,10 @@ update.set(survey.name, "BB").where(survey.name.eq("B")).addBatch();
<para>Delete:</para>
<programlisting language="java"><![CDATA[
insert(survey).values(2, "A").execute();
insert(survey).values(3, "B").execute();
queryFactory.insert(survey).values(2, "A").execute();
queryFactory.insert(survey).values(3, "B").execute();
SQLDeleteClause delete = delete(survey);
SQLDeleteClause delete = queryFactory.delete(survey);
delete.where(survey.name.eq("A")).addBatch();
delete.where(survey.name.eq("B")).addBatch();
assertEquals(2, delete.execute());
@ -984,7 +1000,7 @@ assertEquals(2, delete.execute());
<para>Insert:</para>
<programlisting language="java"><![CDATA[
SQLInsertClause insert = insert(survey);
SQLInsertClause insert = queryFactory.insert(survey);
insert.set(survey.id, 5).set(survey.name, "5").addBatch();
insert.set(survey.id, 6).set(survey.name, "6").addBatch();
assertEquals(2, insert.execute());
@ -1020,44 +1036,19 @@ QEmployee e = new QEmployee("e");
// Insert
Employee employee = new Employee();
employee.setFirstname("John");
Integer id = insert(e).populate(employee).executeWithKey(e.id);
Integer id = queryFactory.insert(e).populate(employee).executeWithKey(e.id);
employee.setId(id);
// Update
employee.setLastname("Smith");
assertEquals(1l, update(e).populate(employee).where(e.id.eq(employee.getId())).execute());
assertEquals(1l, queryFactory.update(e).populate(employee).where(e.id.eq(employee.getId())).execute());
// Query
Employee smith = query().from(e).where(e.lastname.eq("Smith")).uniqueResult(e);
Employee smith = queryFactory.selectFrom(e).where(e.lastname.eq("Smith")).fetchOne();
assertEquals("John", smith.getFirstname());
// Delete
assertEquals(1l, delete(e).where(e.id.eq(employee.getId())).execute());
]]></programlisting>
<para>The factory methods used in the previous example are here:</para>
<programlisting language="java"><![CDATA[
protected SQLUpdateClause update(RelationalPath<?> e) {
return new SQLUpdateClause(Connections.getConnection(), templates, e);
}
protected SQLInsertClause insert(RelationalPath<?> e) {
return new SQLInsertClause(Connections.getConnection(), templates, e);
}
protected SQLDeleteClause delete(RelationalPath<?> e) {
return new SQLDeleteClause(Connections.getConnection(), templates, e);
}
protected SQLMergeClause merge(RelationalPath<?> e) {
return new SQLMergeClause(Connections.getConnection(), templates, e);
}
protected SQLQuery query() {
return new SQLQuery(Connections.getConnection(), templates);
}
assertEquals(1l, queryFactory.delete(e).where(e.id.eq(employee.getId())).execute());
]]></programlisting>
</sect2>
@ -1100,7 +1091,7 @@ NumberExpression<Integer> expression = NumberTemplate.create(Integer.class, "myf
<para>The SQL query and bindings can be extracted via the getSQL method:</para>
<programlisting language="java"><![CDATA[
SQLBindings bindings = query.getSQL(customer.id, customer.firstname, customer.lastname);
SQLBindings bindings = query.getSQL();
System.out.println(bindings.getSQL());
]]></programlisting>