Skip to content

Restrictions

gert-wijns edited this page Jun 6, 2014 · 5 revisions

Adding restrictions

To add restrictions to a query, call the where(...) methods available on the TypeSafeQuery.

Person person = query.from(Person.class);

query.where(person.getAge()).gt(50);      // where(int) returns an instance which can restrict numbers
query.where(person.isMarried()); // where(boolean) returns an instance which can restrict booleans
// different types are also available, each type has type specific restrictions available

hqlQuery.getHql() would yield => 
" from Person hobj1 where person.age > ? and person.married = ?"
with params [50, Boolean.TRUE]

Adding restrictions where both ends are values of entities is just as simple.

Person parent = query.from(Person.class);

Relation childRelation = query.join(parent.getChildRelations());
Person child = query.join(childRelation.getChild());

query.where(child.getName()).eq(parent.getName());

hqlQuery.getHql() would yield => 
"from Person hobj1 join hobj1.childRelations hobj2 join hobj2.child hobj3 where hobj3.name = hobj1.name"

Restriction chaining

It is possible to chain restrictions. All restrictions implement the RestrictionChainable interface.
This interface provides all the possible chaining operations.

Person person = query.from(Person.class);

query.where(person.getAge()).lt(20).
        and(person.getName()).startsWith("Alex"); // chaining and

yields => "from Person hobj1 where hobj1.age < ? and hobj1.name like ?"
with params [20, "Alex%"]

When multiple checks need to be made on the same value, it is possible to chain without having to repeat the original value. A typical case where the same value is checked is a range check. The example below should exaplain how it works.

Building building = query.from(Building.class);

// construction date will be used for the 'after' and the 'before' date check.
query.where(building.getConstructionDate()).after(date1).before(date2);

yields => "from Building hobj1 where hobj1.constructionDate > ? and hobj1.constructionDate < ?"
with params [date1, date2]

Restriction grouping

Most of the time, when a query contains or restrictions, they need to be grouped in order to get the correct result. Restriction grouping can be achieved by creating a group using query.whereGroup(). This creates a grouped restriction, and can be added to the retriction chaining. Restriction chaining is available on the group.

Person person = query.from(Person.class);

RestrictionsGroup nameOrs = query.whereGroup();
nameOrs.where(person.getName()).startsWith("Jef").
           or(person.getName()).startsWith("John");

query.where(person.isMarried()).and(nameOrs);

yields => "from Person hobj1 where hobj1.married = ? and (hobj1.name like ? or hobj1.name like ?)"
with params [Boolean.TRUE, "Jef%", "John%"]

Restriction chaining and restriction grouping can be used combined to create more readable code.

RestrictionsGroupFactory rb = query.factories().getRestrictionsGroupFactory();
Person person = query.from(Person.class);

query.where(person.getName()).startsWith("Jef");
query.where(rb.or(
    rb.where(person.getAge()).lt(10).and(person.getName()).startsWith("John"),
    rb.where(person.getAge()).gt(20).and(person.getName()).startsWith("Emily")));

yields => "from Person hobj1 
where hobj1.name like ? 
  and ((hobj1.age < ? and hobj1.name like ?) or (hobj1.age > ? and hobj1.name like ?))" 
with params ["Jef%", 10, "John%", 20, "Emily%"]

Restrictions with subqueries

Restrictions can also be created with the results of subqueries. In fact, anything which implements the TypeSafeValue<lt;T> can be used as a restriction value. How to create a suquery is covered here. Because subquerying is almost the same as regular querying, the next topic will not be about subquerying.

Next: Selecting specific values

Clone this wiki locally