java - ordenar - hibernate criteria join
JPA e Hibernate-Criterios vs. JPQL o HQL (21)
¿Cuáles son los pros y los contras de usar Criteria o HQL ? La API de criterios 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 usas Criteria y cuando HQL? ¿Qué prefieres en qué casos de uso? ¿O es solo una cuestión de gusto?
Al principio, utilizamos principalmente los criterios en nuestra aplicación, pero después de que fue reemplazado por HQL debido a los problemas de rendimiento.
Principalmente estamos utilizando consultas muy complejas con varias uniones que llevan a múltiples consultas en Criteria pero están muy optimizadas en HQL.
El caso es que usamos solo varias propiedades en objetos específicos 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 (name || '' '' || surname)
pero en Crteria esto no es posible.
Para superar esto, utilizamos ResultTransormers, donde existían métodos donde se implementó dicha concatenación para obtener el resultado necesario.
Hoy usamos principalmente HQL así:
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();
en nuestro caso, los registros devueltos son mapas de propiedades necesarias.
Criteria Api es uno de los buenos conceptos de Hibernate. Según mi punto de vista, estos son los pocos puntos por los cuales podemos marcar la diferencia entre HQL y Criteria Api.
- HQL es realizar operaciones de selección y no selección en los datos, pero los Criterios son solo para seleccionar los datos, no podemos realizar operaciones no seleccionadas 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 Criteria.
- Los criterios solían tomar más tiempo para ejecutar que HQL.
- Con Criteria estamos seguros con la Inyección SQL debido a su generación de consultas dinámicas, pero en HQL, ya que sus consultas son fijas o parametrizadas, no existe una caja fuerte contra Inyección SQL.
Criteria es una API orientada a objetos, mientras que HQL significa concatenación de cadenas. Eso significa que todos los beneficios de la orientación a objetos se aplican:
- Si 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 de Criteria válidos pueden convertirla en un árbol de Criterios. Efectivamente, las clases de Criterios están más restringidas.
- Con la función de autocompletar, el OO es más visible (y por lo tanto más fácil de usar, al menos para mí). No necesariamente tiene que recordar qué partes de la consulta van a dónde; el IDE puede ayudarte
- Tampoco es necesario recordar los detalles de la sintaxis (como qué símbolos van a dónde). Todo lo que necesitas saber es cómo llamar a los métodos y crear objetos.
Dado que HQL es muy parecido a SQL (que la mayoría de los desarrolladores ya conocen muy bien), estos argumentos de "no es necesario recordarlos" no tienen tanto peso. Si HQL fuera más diferente, entonces esto sería más importante.
En su mayoría prefiero consultas de criterios para consultas dinámicas. Por ejemplo, es mucho más fácil agregar algunos pedidos dinámicamente o dejar 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, por ejemplo, para diferentes tipos de combinaciones.
Esta publicación es bastante antigua. La mayoría de las respuestas hablan de criterios de Hibernate, no de JPA. JPA 2.1 agregó CriteriaDelete / CriteriaUpdate, y EntityGraph que controla qué exactamente buscar. Criteria API es mejor ya que Java es OO. Es por eso que se crea JPA. Cuando se compila JPQL, se traducirá al árbol AST (modelo OO) antes de convertirse a SQL.
HQL puede causar problemas de seguridad como la inyección de SQL.
Hay otra manera. Terminé creando un analizador HQL basado en la sintaxis original de hibernación, por lo que primero analiza el HQL y luego podría inyectar dinámicamente parámetros dinámicos o agregar automáticamente algunos filtros comunes para las consultas HQL. Funciona muy bien
Hay una diferencia en términos de rendimiento entre HQL y criteriaQuery, cada vez que se inicia una consulta utilizando criteriaQuery, 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, demorando más tiempo en ejecutarse.
Con respecto a las estrategias de captura [http://www.hibernate.org/315.html]
- Criteria respeta la configuración de la pereza en sus asignaciones y garantiza que se cargue lo que desea que se cargue. Esto significa que una consulta de Criterios puede resultar en varias sentencias SELECT inmediatas de SQL para obtener el subgrafo con todas las asociaciones y colecciones asignadas no perezosas. Si desea cambiar el "cómo" e incluso el "qué", use setFetchMode () para habilitar o inhabilitar la extracción de la combinación externa para una colección o asociación en particular. Las consultas de criterios también respetan completamente la estrategia de búsqueda (unirse vs seleccionar vs subseleccionar).
- HQL respeta la configuración de la pereza en sus asignaciones y garantiza que se cargue lo que desea que se cargue. Esto significa que una consulta HQL puede resultar en varias sentencias SELECT inmediatas de SQL para obtener el subgrafo con todas las asociaciones y colecciones asignadas no perezosas. Si desea cambiar el "cómo" e incluso el "qué", use LEFT JOIN FETCH para habilitar la recuperación de la unión externa para una colección particular o una asociación de uno a uno o una asociación de uno a uno que pueda ser anulada, o JOIN FETCH para habilitar Obtención de unión interna para una asociación de varios a uno o de uno a uno que no admiten nulos. Las consultas HQL no respetan ningún fetch = "join" definido en el documento de mapeo.
La API de criterios 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 evitar ataques de Inyección SQL al crear consultas dinámicas, la API de Criteria es una muy buena opción.
Las consultas de criterios son menos expresivas y puede terminar fácilmente con una consulta generada por SQL muy complicada e ineficiente. Una vez me uní a una gran aplicación empresarial en la que 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 terminaríamos.
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 de HQL que los criterios.
La mayoría de los casos de uso de consultas de entidades no requieren cláusulas dinámicas, por lo que puede implementar la mayoría de las consultas con JPQL y dejar los Criterios 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. Echa un vistazo a este artículo para más información .
La consulta de criterios para dinámicamente podemos construir consultas en función de nuestras entradas ... En caso de que Hql query sea la consulta estática, una vez que construimos no podemos cambiar la estructura de la consulta.
La mayoría de las respuestas aquí son engañosas y mencionan que las Criteria Queries
son más lentas que HQL
, lo que en realidad no es el caso.
Si profundiza y realiza algunas pruebas, verá que las consultas de criterios funcionan mucho mejor que el HQL normal .
Y también con Criteria Query obtiene un control orientado a objetos que no está disponible con HQL .
Para más información lea esta respuesta here .
Los criterios api proporcionan una característica distinta que Ni SQL ni HQL proporcionan. es decir. Permite la compilación del tiempo de verificación de una consulta.
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 manera de especificar la pista necesaria.
Puedes encontrar más información aquí:
No quiero patear a un caballo muerto aquí, pero es importante mencionar que las consultas de Criteria ahora están en desuso. Utilice HQL.
Para mí, el mayor logro de Criteria es la API de ejemplo, donde puede pasar un objeto e hibernar creará una consulta basada en esas propiedades de objeto.
Además de eso, la API de criterios tiene sus peculiaridades (creo que el equipo de hibernación está revisando la API), como:
- a criteria.createAlias ("obj") fuerza una combinación interna en lugar de una posible combinación externa
- no puedes crear el mismo alias dos veces
- Algunas cláusulas de SQL no tienen contrapartida de criterios simples (como una subselección)
- etc.
Tiendo a usar HQL cuando quiero consultas similares a sql (eliminar de los Usuarios donde status = ''bloqueado''), y tiendo a usar criterios cuando no quiero usar el anexado de cadenas.
Otra ventaja de HQL es que puede definir todas sus consultas de antemano e incluso externalizarlas a un archivo o algo así.
Para mí, los criterios son bastante fáciles de entender y hacer consultas dinámicas. Pero la falla que digo hasta ahora es que carga todas las relaciones de muchos-uno, etc. porque solo tenemos tres tipos de FetchModes, es decir, Seleccionar, Proxy y Predeterminado, y en todos estos casos carga muchos-uno (puede ser que esté equivocado si es así, ayuda) Sacarme :))
El segundo problema con los Criterios es que carga el objeto completo, es decir, si solo quiero cargar EmpName de un empleado, no se le ocurrirá esto. En este caso se generará un objeto Employee completo y puedo obtener EmpName debido a que realmente funciona mal en reportando donde como HQL solo carga (no carga asociación / relaciones) lo que quieres, incrementa el rendimiento muchas veces.
Una de las características de Criteria es que protegerá u de SQL Injection debido a su generación de consultas dinámicas en la que, como en HQL, ya que sus consultas son fijas o parametrizadas, no están a salvo de SQL Injection.
Además, si escribe HQL en sus archivos aspx.cs, entonces estará estrechamente relacionado con su DAL.
En general, mi conclusión es que hay lugares en los que no se puede vivir sin informes tipo HQL, por lo que es mejor utilizar los Criteria.
Para usar lo mejor de ambos mundos, la expresividad y concisión de HQL y la naturaleza dinámica de Criteria consideran el uso de Querydsl .
Querydsl admite JPA / Hibernate, JDO, SQL y colecciones.
Soy el mantenedor de Querydsl, por lo que esta respuesta es parcial.
Por lo general, utilizo Criterios cuando no sé qué entradas se utilizarán en qué datos. Como en un formulario de búsqueda donde el usuario puede ingresar de 1 a 50 elementos y no sé qué buscarán. Es muy fácil simplemente 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. HQL es genial, sin embargo, cuando sé exactamente lo que quiero.
También prefiero consultas de criterios para consultas dinámicas. Pero prefiero hql para las consultas de eliminación, por ejemplo, si se eliminan 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 consulta de eliminación donde n es número de secundaria registros de la tabla.
HQL es mucho más fácil de leer, más fácil de depurar con herramientas como el complemento Hibernate de Eclipse y más fácil de iniciar sesión. Las consultas de criterios son mejores para crear consultas dinámicas en las que gran parte del comportamiento se determina en tiempo de ejecución. Si no sabe SQL, podría entender el uso de consultas de criterios, pero en general prefiero HQL si sé lo que quiero por adelantado.
- HQL es realizar operaciones de selección y no selección en los datos, pero Criterios es solo para seleccionar los datos, no podemos realizar operaciones no seleccionadas 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 Criteria
- Criterios utilizados para tomar más tiempo para ejecutar luego HQL
- Con Criteria estamos seguros con SQL Injection debido a su generación de consultas dinámicas, pero en HQL, ya que sus consultas son fijas o parametrizadas, no existe una caja fuerte contra SQL Injection.