This is convenience layer on top of JPA Criteria API which allows to write following queries:
QEmployee_ employee = new QEmployee_();
List<Employee> employees = query.select(Employee.class)
.where(employee.fullName.like("John%"))
.orderBy(employee.age.asc())
.limit(20, 10)
.getResultList();
Design goals used during creation of this library:
- Reuse all available JPA functionality and infrastructure
- Be simple and minimalistic so that any developer was able to change library code just after few hours of code investigation. Version 1.x used JPA metamodel which imposes serious limitations on the possible query syntax. Version 2.x works with own custom generated metamodel. Main motivation for generating own metamodel is to improve query syntax compared to version 1.x. Version 3.x has swicthed to Jakarta JPA packages
- Provide simpler, more convenient and shorter syntax compared to JPA Criteria API
Add dependency to your project:
<dependency>
<groupId>io.github.sveryovka</groupId>
<artifactId>easy-criteria</artifactId>
<version>3.0.0</version>
</dependency>
Metamodel is generated by easycriteria.meta.modelgen.JPACriteriaProcessor
class which is Java annotation processor and is invoked during build process. For each JPA entity class own metamodel class will be generated using following naming pattern "Q" + className + "_". If you do not have Java annotation processors explicitly disabled for your build this annotation processor will be triggered automatically. All you have to do is to have "easy-criteria" added as dependency.
You need to have instance of JPA Entity Manager to create and execute query
List<Employee> employees = new JPAQuery(entityManager).select(Employee.class).getResultList();
QEmployee_ employee = new QEmployee_();
List<Employee> employees = query.select(employee)
.where(employee.fullName.like("John%"))
.orderBy(employee.age.asc())
.limit(20, 10)
.getResultList();
Please pay attention that before executing query you need to create instance of metamodel class QEmployee_
to be able to use it in query.
API has two methods:
limit(int rowCount)
limit(int offset, int rowCount)
Example:
List<Employee> employees = query.select(Employee.class)
.limit(20, 10)
.getResultList();
To reproduce SQL query
select * from employee
where
fullName = 'Something'
or (fullName = 'Other 1' and age = 5)
or (fullName = 'Name 1' and age = 1)'
you need to use following Java code
QEmployee_ employee = new QEmployee_();
List<Employee> employees = query.select(Employee.class)
.where(
employee.fullName.eq("Something")
.or(
employee.fullName.eq("Other 1")
.and(employee.age.eq(5))
).or(
employee.fullName.like("Name 1")
.and(employee.age.eq(1))
)
)
.getResultList();
Object model:
@Entity
public class Project {
private String name;
...
@OneToOne
private HomeAnimal homeAnimal;
}
@Entity
public class HomeAnimal extends Animal {
private String owner;
...
}
We want join "Project" and "HomeAnimal" and filter results where homeAnimal.owner ="owner1"
QLargeProject_ largeProject = new QLargeProject_();
QHomeAnimal_ homeAnimal = new QHomeAnimal_();
List<LargeProject> projects = query.select(LargeProject.class)
.join(largeProject.homeAnimal, JoinType.INNER, homeAnimal)
.where(homeAnimal.owner.eq("owner1"))
.getResultList();
In this example when we perform join join(largeProject.homeAnimal, JoinType.INNER, homeAnimal)
we specify join type JoinType.INNER
and join table alias homeAnimal
which is later used to filter results.
To create instance of "subquery" you need to have instance of "query" created first.
QEmployee_ employee = new QEmployee_();
EasyCriteriaQuery<Employee, Employee> query = new JPAQuery(entityManager).select(Employee.class);
EasyCriteriaSubquery<Employee, Integer> subQuery = query.subquerySelect(employee.id).where(employee.fullName.eq("fullName1"));
List<Employee> emp = query.where(employee.id.in(subQuery)).getResultList()
Currently map joins are not supported. Use JPA API directly to construct queries which require map joins.
If you are looking for typesafe ways to execute SQL queries in Java please also check