The goal of TypeSafeQueryBuilder
is to allow writing queries using your hibernate configured entity classes rather than hand-coded HQL strings.
For an overview of the available functionality, see Functionality overview. The rest of this page will be a basic tutorial to get started. Basic knowledge of HQL is required to understand the examples and functionality overview.
Add library using maven:
<dependency>
<groupId>com.github.gert-wijns</groupId>
<artifactId>TypeSafeQueryBuilder</artifactId>
<version>4.0.0</version>
</dependency>
To obtain a query, create a TypeSafeQueryDao with the hibernate sessionFactory and call the createQuery()
method on it.
TypeSafeQueryDao dao = new TypeSafeQueryDaoImpl(sessionFactory);
TypeSafeRootQuery query = dao.createQuery();
To list the query results, call the doQuery(TypeSafeRootQuery query)
method available on the TypeSafeQueryDao.
// build useful query and then use doQuery to list the results:
List<InterestingData> results = dao.doQuery(query);
To query from an entity, use the query.from(Class<?> entityClass)
method. This will return a proxy of the entityClass to continue building the query.
Person person = query.from(Person.class); // would select people
=> "from Person hobj1" // Note: automatic unique alias provided
See also:
There is a wide range of select options for various cases. This example will deal with selecting a subset of entity properties into a dto.
To select data into a dto, create a dto proxy using the query.select(Class<?> dtoClass)
method. This will return a proxy of the dtoClass to which data of the entity can be set using a setter of the dto proxy with a getter of the entity proxy. Note: calling the setter and getter will only bind the property to be selected into the dto. The value is only available after listing the query results.
// select creates proxy instance of dto class
PersonDto personDto = query.select(PersonDto.class);
// binds person age to the personAge property
personDto.setPersonAge(person.getAge());
=> "select hobj1.age as personAge from Person hobj1"
See also:
To specificy the where clause of a query, start by using the query.where(property)
method. Depending on the property type, a list of relevant methods to build the restriction will be available. For example: using a Date as property, it is possible to check if the date is not before some other date while this check would not be available when using a Number property.
query.where(person.getAge()).gt(50)
=> "from Person hobj1 where hobj1.age > :np1" [np1=50]
Adding more and
restrictions and grouping or
restrictions is covered in the functionality overview.
See also:
Entities can be joined by using the query.join(...)
methods.
Additionally, entities may also be joined implicitely by using the getter method of an entity proxy.
It is only possible to obtain a proxy of a collection relation by using the join(...)
methods.
// join and obtain a proxy of a collection element
Relation childRelation = query.join(parent.getChildRelations());
// join implicitly, returns a proxy of the getter type
Person child = childRelation.getChild();
=> "from Person hobj1 join hobj1.childRelations hobj2 join hobj2.child hobj3"
Entities could also be joined even when there is no explicit object relation using class joins.
// join to obtain a proxy of an entity, parent is needed to link the joined entity to the parent
Relation childRelation = query.join(parent, Relation.class, ClassJoinType.Inner);
// joinWith is required for class joins, specifies how the entities are related in sql
query.joinWith(childRelation).where(parent.getId()).eq(childRelation.getParent().getId());
=> from Person hobj1 join Relation hobj2 on hobj1.id = hobj2.parent.id
See also:
Sorting values can be done by using the query.orderBy()
method and subsequently calling the desc(...)
or asc(...)
methods. These methods can be chained to sort by multiple values.
query.orderBy().desc(person.getName()).
asc(person.getAge());
=> "from Person hobj1 order by hobj1.name desc, hobj1.age"
See also:
Grouping values can be done by using the query.groupBy(...)
method.
PersonDto personDto = query.select(PersonDto.class);
personDto.setPersonAge(person.getAge());
query.groupBy(person.getAge());
=> "select hobj1.age as personAge from Person hobj1 group by hobj1.age"
See also:
Having restrictions can be add by using query.having(...)
.
Building building = query.from(Building.class);
query.select(building.getConstructionDate());
query.groupBy(building.getConstructionDate());
Date dateArg = new Date();
query.having(building.getConstructionDate()).after(dateArg);
=> "select hobj1.constructionDate
from Building hobj1
group by hobj1.constructionDate
having hobj1.constructionDate > :np1"
params [np1=dateArg]