-
Couldn't load subscription status.
- Fork 8
Restrictions
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.