Introducción a la API de Criterios

Hay dos formas de escribir consultas de base de datos en Hibernate:

  • Lenguaje de consulta de Hibernate
  • API de criterios

Ya conociste al primero hace mucho tiempo, es hora de familiarizarse con la API de Criteria. Esta es una herramienta muy poderosa, en algún momento fue incluso más popular que HQL. Ahora ya no es tan popular, pero para algunas tareas definitivamente será una mejor solución que HQL.

En cualquier caso, no puede aprender Hibernate sin familiarizarse con la API de criterios. Escribamos un pequeño ejemplo y luego lo analizaremos. Por ejemplo, solicitaremos todos los empleados (Empleado) de la base de datos. Esto es lo que obtendremos:

CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Employee> critQuery = builder.createQuery(Employee.class);

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Query<Employee> query = session.createQuery(critQuery);
List<Employee> results = query.getResultList();

Parece complicado. Escribamos la misma consulta HQL para comparar:

String hqlQuery = "from Employee";

Query<Employee> query = session.createQuery(hqlQuery);
List<Employee> results = query.getResultList();

Tenga en cuenta que las dos últimas líneas de ambos ejemplos son casi idénticas: creamos un objeto Consulta y lo usamos para obtener una Lista. Esto sugiere que el resto de las líneas están haciendo algo idéntico.

Mira las líneas 3 y 4 del primer ejemplo:

Root<Employee> root = critQuery.from(Employee.class);
critQuery.select(root);

Escribámoslos en una sola línea:

critQuery.select(critQuery.from(Employee.class));

¿No te recuerda a nada? Y si lo coloreas un poco diferente:

critQuery.select(critQuery.from(Employee.class));

Sí, esta es una construcción tan complicada de la consulta SELECT FROM.

Ejemplos de trabajo con la API de criterios

Para una mejor comprensión, solo daré algunos ejemplos.

Solicitud 1 . Obtenga todos los empleados con un salario superior a 10 mil:

critQuery.select(critQuery.from(Employee.class)).where(builder.gt(root.get("salary"), 10000));

Solicitud 2 . Obtenga todos los empleados con un salario de menos de 50 mil:

critQuery.select(critQuery.from(Employee.class)).where(builder.lt(root.get("salary"), 50000));

Solicitud 3 . Obtenga todos los empleados cuyo puesto de trabajo contenga la palabra "prueba":

critQuery.select(critQuery.from(Employee.class)).where(builder.like(root.get("occupation"), "%test%"));

Solicitud 4 . Obtenga todos los empleados con un salario de 10 a 50 mil:

critQuery.select(critQuery.from(Employee.class)).where(builder.between(root.get("salary"), 10000, 50000));

Solicitud 5 . Obtenga todos los empleados cuyo nombre es nulo:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNull(root.get("name")));

Solicitud 6 . Obtenga todos los empleados cuyo nombre no sea nulo:

critQuery.select(critQuery.from(Employee.class)).where(builder.isNotNull(root.get("name")));

Es una forma tan complicada de construir una consulta:

  • Primero obtienes el objetoConstructor de Criterios.
  • Luego úsalo para crear un objeto.Consulta de criterios.
  • Luego comienzas a agregarle partes conConsulta de criteriosYConstructor de Criterios.

Así es como puede establecer parámetros para:

  • SELECCIONAR
  • DE
  • DÓNDE

también usandoConstructor de Criteriospuede construir diferentes condiciones para DONDE.

Trabajo avanzado con Criteria API

Con la API de criterios, puede construir una consulta de cualquier complejidad. Y esta es una gran noticia. Por ejemplo, desea una cláusula WHERE compleja. Aquí está cómo hacerlo:

Predicate greaterThan = builder.gt(root.get("salary"), 1000);
Predicate testers = builder.like(root.get("occupation"), "test%");

critQuery.select(critQuery.from(Employee.class)).where(builder.or(greaterThan, testers));

Si desea escribir AND en lugar de OR, solo necesita cambiar la última línea:

critQuery.select(critQuery.from(Employee.class)).where(builder.and(greaterThan, testers));

Todo es realmente muy simple. Déjame darte una tabla con algunas comparaciones:

sql Método registro completo
a<b es (a, b) constructor.lt(a, b)
a > b gt(a, b) constructor.gt(a, b)
a o B o (a,b) constructor.o(a, b)
a y B y (a,b) constructor.y(a,b)
un ME GUSTA b como (a, b) constructor.como(a, b)
a ENTRE (c, d) entre (a, c, d) constructor.entre(a, c, d)
a ES NULO es nulo (a) constructor.isNull(a)
a NO ES NULO no es nulo (a) builder.isNotNull(a)

Todo es simple, ¿no?

¿Y cómo agregamos clasificación a la consulta? Muy simple:

critQuery.select( critQuery.from(Employee.class) );
critQuery.where( builder.and(greaterThan, testers) );
critQuery.orderBy( builder.asc(root.get("salary"), builder.desc(root.get("joinDate") )

Solo llamas al objetoConsulta de criteriosorderBy () y pásele los parámetros requeridos.

Así es como se vería la misma consulta en HQL. Comparar:

select * from Employee
where (…) and (…)
order by 'salary' asc, 'joinDate' desc

Solo necesitas recordar 3 cosas:

  • Los operadores clave como SELECT, FROM, WHERE se llaman en un objetoConsulta de criterios.
  • Los operadores auxiliares como AND, OR, DESC se llaman en el objetoConstructor de Criterios.
  • Los nombres de campo se toman del objeto a través de get()raíz.