Pregunta

¿Cuáles son las ventajas y desventajas de usar Criterios o HQL ? Criteria API es una buena forma orientada a objetos para expresar consultas en Hibernate, pero a veces las Consultas de Criterios son más difíciles de entender / construir que HQL.

¿Cuándo utiliza Criterios y cuándo HQL? ¿Qué prefieres en qué casos de uso? ¿O es solo una cuestión de gustos?

¿Fue útil?

Solución

Prefiero sobre todo consultas de criterios para consultas dinámicas. Por ejemplo, es mucho más fácil agregar algunos pedidos dinámicamente o dejar fuera algunas partes (por ejemplo, restricciones) dependiendo de algún parámetro.

Por otro lado, estoy usando HQL para consultas estáticas y complejas, porque es mucho más fácil de entender / leer HQL. Además, creo que HQL es un poco más potente, p. para diferentes tipos de unión.

Otros consejos

Hay una diferencia en términos de rendimiento entre HQL y criterioQuery, cada vez que activa una consulta utilizando criterioQuery, crea un nuevo alias para el nombre de la tabla que no se refleja en la última caché consultada para ningún DB. Esto lleva a una sobrecarga de compilar el SQL generado, lo que lleva más tiempo ejecutarlo.

Con respecto a las estrategias de obtención [http://www.hibernate.org/315.html]

  
      
  • Criteria respeta la configuración de pereza en sus asignaciones y garantiza que se carga lo que desea cargar. Esto significa que una consulta de Criterios podría dar como resultado varias sentencias SELECT inmediatas de SQL para obtener el subgrafo con todas las asociaciones y colecciones mapeadas no perezosas. Si desea cambiar el " cómo " e incluso el "qué", use setFetchMode () para habilitar o deshabilitar la búsqueda de combinación externa para una colección o asociación particular. Las consultas de criterios también respetan completamente la estrategia de obtención (unirse vs seleccionar vs subseleccionar).
  •   
  • HQL respeta la configuración de la pereza en sus asignaciones y garantiza que se cargue lo que desea cargar. Esto significa que una consulta HQL podría generar varias sentencias SELECT inmediatas de SQL para obtener el subgrafo con todas las asociaciones y colecciones mapeadas no perezosas. Si desea cambiar el " cómo " e incluso el '' qué '', use LEFT JOIN FETCH para habilitar la búsqueda de unión externa para una colección particular o asociación anulable de muchos a uno o uno a uno, o JOIN FETCH para habilitar la búsqueda de unión interna para un no anulable asociación muchos a uno o uno a uno. Las consultas HQL no respetan ninguna búsqueda = " unirse " definido en el documento de mapeo.
  •   

Criteria es una API orientada a objetos, mientras que HQL significa concatenación de cadenas. Eso significa que se aplican todos los beneficios de la orientación a objetos:

  1. Todo lo demás es igual, la versión OO es algo menos propensa a errores. Cualquier cadena antigua podría agregarse a la consulta HQL, mientras que solo los objetos Criteria válidos pueden convertirse en un árbol Criteria. Efectivamente, las clases de Criterios están más restringidas.
  2. Con autocompletar, el OO es más reconocible (y por lo tanto más fácil de usar, al menos para mí). No necesariamente necesita recordar qué partes de la consulta van a dónde; el IDE puede ayudarlo
  3. Tampoco es necesario recordar los detalles de la sintaxis (como qué símbolos van a dónde). Todo lo que necesita saber es cómo llamar a métodos y crear objetos.

Dado que HQL se parece mucho a SQL (que la mayoría de los desarrolladores ya conocen muy bien), entonces estos "no tienen que recordar". Los argumentos no tienen tanto peso. Si HQL fuera más diferente, entonces esto sería más importante.

Usualmente uso Criterios cuando no sé qué entradas se usarán en qué datos. Al igual que en un formulario de búsqueda en el que el usuario puede ingresar cualquiera de 1 a 50 elementos y no sé qué buscarán. Es muy fácil agregar más a los criterios a medida que reviso lo que el usuario está buscando. Creo que sería un poco más problemático poner una consulta HQL en esa circunstancia. Sin embargo, HQL es excelente cuando sé exactamente lo que quiero.

HQL es mucho más fácil de leer, más fácil de depurar usando herramientas como el complemento Eclipse Hibernate, y más fácil de iniciar sesión. Las consultas de criterios son mejores para crear consultas dinámicas donde gran parte del comportamiento se determina en tiempo de ejecución. Si no conoce SQL, podría entender el uso de consultas de Criterios, pero en general prefiero HQL si sé lo que quiero por adelantado.

Los criterios son la única forma de especificar búsquedas de claves naturales que aprovechan la optimización especial en el caché de consultas de segundo nivel. HQL no tiene ninguna forma de especificar la sugerencia necesaria.

Puede encontrar más información aquí:

Criterios Api es uno de los buenos conceptos de Hibernate. Según mi punto de vista, estos son los pocos puntos por los cuales podemos hacer la diferencia entre HQL y Criterios Api

  1. HQL es realizar operaciones tanto selectivas como no selectivas en los datos, pero los Criterios son solo para seleccionar los datos, no podemos realizar operaciones no selectivas utilizando criterios.
  2. HQL es adecuado para ejecutar consultas estáticas, mientras que Criteria es adecuado para ejecutar consultas dinámicas
  3. HQL no admite el concepto de paginación , pero podemos lograr la paginación con Criterios.
  4. Los criterios solían tomar más tiempo para ejecutarse que HQL.
  5. Con Criteria estamos seguros con SQL Injection debido a su generación dinámica de consultas, pero en HQL ya que sus consultas son fijas o parametrizadas, no hay seguridad de SQL Injection

Para mí, Criteria es bastante fácil de entender y hacer consultas dinámicas. Pero la falla que digo hasta ahora es que carga todas las relaciones de muchos, etc., porque solo tenemos tres tipos de FetchModes, es decir, Seleccionar, Proxy y Predeterminado, y en todos estos casos carga muchos (uno puede estar equivocado si es así, ayuda yo fuera :))

El segundo problema con los Criterios es que carga el objeto completo, es decir, si solo quiero cargar EmpName de un empleado, no aparece este hecho, aparece el objeto Employee completo y puedo obtener EmpName de él debido a esto realmente funciona mal en los informes . donde como HQL solo carga (no cargó asociación / relaciones) lo que desea, así que aumente el rendimiento muchas veces.

Una característica de Criteria es que te protegerá de la inyección de SQL debido a su generación dinámica de consultas, donde en HQL tus consultas son fijas o parametrizadas, por lo que no están a salvo de la inyección de SQL.

Además, si escribe HQL en sus archivos aspx.cs, entonces está estrechamente relacionado con su DAL.

En general, mi conclusión es que hay lugares en los que no puedes vivir sin HQL, como informes, así que úsalos de otra forma. Los criterios son más fáciles de administrar.

Para usar lo mejor de ambos mundos, la expresividad y concisión de HQL y la naturaleza dinámica de Criteria consideran usar Querydsl .

Querydsl admite JPA / Hibernate, JDO, SQL y Collections.

Soy el mantenedor de Querydsl, por lo que esta respuesta es parcial.

Para mí, la mayor victoria en Criteria es la API de ejemplo, donde puede pasar un objeto e hibernar generará una consulta basada en esas propiedades del objeto.

Además de eso, la API de criterios tiene sus peculiaridades (creo que el equipo de hibernación está reelaborando la API), como:

  • un criterio.createAlias ??(" obj ") fuerza una unión interna en lugar de una posible unión externa
  • no puedes crear el mismo alias dos veces
  • algunas cláusulas sql no tienen una contraparte de criterios simples (como una subselección)
  • etc.

Tiendo a usar HQL cuando quiero consultas similares a sql (eliminar de usuarios donde status = 'bloqueado'), y tiendo a usar criterios cuando no quiero usar el agregado de cadenas.

Otra ventaja de HQL es que puede definir todas sus consultas de antemano e incluso externalizarlas a un archivo más o menos.

Criteria API es más adecuada para consultas generadas dinámicamente cuando los filtros de consulta se aplican dinámicamente en tiempo de ejecución. Por lo tanto, para prevenir SQL Ataques de inyección al crear consultas dinámicas, Criteria API es una muy buena opción.

Las consultas de criterios son menos expresivas y puede terminar fácilmente con un Consulta generada por SQL . Una vez me uní a una aplicación empresarial grande donde Criteria API era el método de consulta predeterminado y ni siquiera una revisión exhaustiva del código podría superar el horror de no saber con qué consultas SQL íbamos a terminar.

JPQL o HQL es mucho más expresivo y es mucho más fácil predecir la consulta SQL generada asociada. También es mucho más fácil revisar las consultas HQL que los Criterios.

La mayoría de los casos de uso de consulta de entidades no requieren cláusulas where dinámicas para que pueda implementar la mayoría de las consultas con JPQL mientras deja Criteria para las dinámicas.

Vale la pena señalar que seleccionar entidades con JPQL o Criteria API tiene sentido si necesita modificarlas. De lo contrario, una proyección DTO funciona mejor. Consulte este artículo para obtener más información .

La API de criterios proporciona una característica distinta que ni SQL ni HQL proporcionan. es decir. Permite la verificación en tiempo de compilación de una consulta.

Al principio utilizamos principalmente Criterios en nuestra aplicación, pero después de que se reemplazó con HQL debido a problemas de rendimiento.
Principalmente estamos usando consultas muy complejas con varias combinaciones que conducen a múltiples consultas en Criteria pero están muy optimizadas en HQL.
El caso es que usamos solo varias propiedades en un objeto específico y no en objetos completos. Con Criteria, el problema también era la concatenación de cadenas.
Digamos que si necesita mostrar el nombre y el apellido del usuario en HQL, es bastante fácil (nombre || '' || apellido) pero en Crteria esto no es posible.
Para superar esto, utilizamos ResultTransormers, donde había métodos en los que se implementaba dicha concatenación para obtener el resultado necesario.
Hoy usamos principalmente HQL de esta manera:

String hql = "select " +
            "c.uuid as uuid," +
            "c.name as name," +
            "c.objective as objective," +
            "c.startDate as startDate," +
            "c.endDate as endDate," +
            "c.description as description," +
            "s.status as status," +
            "t.type as type " +
            "from " + Campaign.class.getName() + " c " +
            "left join c.type t " +
            "left join c.status s";

Query query =  hibernateTemplate.getSessionFactory().getCurrentSession().getSession(EntityMode.MAP).createQuery(hql);
query.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
return query.list();

así que en nuestro caso los registros devueltos son mapas de propiedades necesarias.

  • HQL es realizar operaciones tanto selectivas como no selectivas en los datos, pero los criterios son solo para seleccionar los datos, no podemos realizar operaciones no selectivas utilizando criterios
  • HQL es adecuado para ejecutar consultas estáticas, mientras que Criteria es adecuado para ejecutar consultas dinámicas
  • HQL no admite el concepto de paginación, pero podemos lograr la paginación con Criterios
  • Los criterios solían tomar más tiempo para ejecutarse que HQL
  • Con Criteria estamos seguros con la inyección de SQL debido a su generación de consultas dinámicas, pero en HQL ya que sus consultas son fijas o parametrizadas, no hay seguridad de la inyección de SQL.

fuente

Consulta de criterios para dinámicamente podemos construir consultas basadas en nuestras entradas ... En el caso de la consulta Hql es la consulta estática una vez que construimos no podemos cambiar la estructura de la consulta.

No quiero patear un caballo muerto aquí, pero es importante mencionar que las consultas de Criterios ahora están en desuso. Use HQL.

También prefiero las consultas de criterios para consultas dinámicas. Pero prefiero hql para eliminar consultas, por ejemplo, si elimina todos los registros de la tabla secundaria para la identificación principal 'xyz', HQL lo logra fácilmente, pero para los criterios API primero debemos disparar n número de consultas de eliminación donde n es el número de hijos registros de tabla.

La mayoría de las respuestas aquí son engañosas y mencionan que Consultas de criterios son más lentas que HQL , lo que en realidad no es el caso.

Si profundiza y realiza algunas pruebas, verá Las consultas de criterios funcionan mucho mejor que el HQL normal .

Y también con Criteria Query obtienes control orientado a objetos que no está allí con HQL .

Para obtener más información, lea esta respuesta aquí .

Hay otra forma. Terminé creando un analizador HQL basado en la sintaxis original de hibernación, por lo que primero analiza el HQL y luego puede inyectar dinámicamente parámetros dinámicos o agregar automáticamente algunos filtros comunes para las consultas HQL. ¡Funciona muy bien!

Esta publicación es bastante antigua. La mayoría de las respuestas hablan de criterios de Hibernate, no de criterios JPA. JPA 2.1 agregó CriteriaDelete / CriteriaUpdate y EntityGraph que controla exactamente qué buscar. Criterios API es mejor ya que Java es OO. Por eso se crea JPA. Cuando se compila JPQL, se traducirá al árbol AST (modelo OO) antes de traducirse a SQL.

HQL puede causar preocupaciones de seguridad como inyección SQL.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top