mirror of
https://github.com/querydsl/querydsl.git
synced 2026-06-13 21:01:01 +08:00
Merge pull request #1345 from querydsl/reference-docs
Update reference docs
This commit is contained in:
commit
bbdfe863e1
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user