Quais são os prós e os contras do uso de Critérios ou HQL ? A API de critérios é uma boa maneira orientada a objetos para expressar consultas no Hibernate, mas às vezes as consultas de critérios são mais difíceis de entender / criar do que o HQL.
Quando você usa Critérios e quando HQL? O que você prefere em quais casos de uso? Ou é apenas uma questão de gosto?
Respostas:
Eu prefiro consultas de critério para consultas dinâmicas. Por exemplo, é muito mais fácil adicionar alguns pedidos dinamicamente ou deixar algumas peças (por exemplo, restrições) de fora, dependendo de algum parâmetro.
Por outro lado, estou usando o HQL para consultas estáticas e complexas, porque é muito mais fácil entender / ler o HQL. Além disso, acho que o HQL é um pouco mais poderoso, por exemplo, para diferentes tipos de junção.
fonte
Há uma diferença em termos de desempenho entre HQL e criterQuery, sempre que você dispara uma consulta usando o critérioQuery, ele cria um novo alias para o nome da tabela que não reflete no último cache consultado para nenhum banco de dados. Isso leva a uma sobrecarga de compilação do SQL gerado, levando mais tempo para ser executado.
Sobre estratégias de busca [http://www.hibernate.org/315.html]
fonte
Critérios é uma API orientada a objetos, enquanto HQL significa concatenação de cadeias. Isso significa que todos os benefícios da orientação a objetos se aplicam:
Como o HQL é muito parecido com o SQL (que a maioria dos desenvolvedores já conhece muito bem), esses argumentos "não precisam se lembrar" não têm tanto peso. Se o HQL fosse mais diferente, isso seria mais importante.
fonte
Normalmente, uso Critérios quando não sei quais serão as entradas em quais dados. Como em um formulário de pesquisa onde o usuário pode inserir de 1 a 50 itens e não sei o que ele estará procurando. É muito fácil anexar mais aos critérios à medida que passo verificando o que o usuário está procurando. Eu acho que seria um pouco mais problemático colocar uma consulta HQL nessa circunstância. HQL é ótimo quando eu sei exatamente o que eu quero.
fonte
O HQL é muito mais fácil de ler, mais fácil de depurar usando ferramentas como o plug-in Eclipse Hibernate e mais fácil de registrar. As consultas de critério são melhores para criar consultas dinâmicas em que muito do comportamento é determinado em tempo de execução. Se você não conhece SQL, eu poderia entender usando consultas de Critérios, mas no geral prefiro HQL se souber o que quero antecipadamente.
fonte
Os critérios são a única maneira de especificar pesquisas de chave natural que aproveitam a otimização especial no cache de consulta de segundo nível. O HQL não tem como especificar a dica necessária.
Você pode encontrar mais algumas informações aqui:
fonte
Critérios A API é um dos bons conceitos do Hibernate. de acordo com o meu ponto de vista, esses são os poucos pontos pelos quais podemos fazer a diferença entre HQL e Critérios API
fonte
limit offset:rows
Alguns pontos A paginação existe no HQL: você pode usar No hql, você pode evitar a injeção de sql usandosetParameter
Para usar o melhor dos dois mundos, a expressividade e concisão do HQL e a natureza dinâmica dos Critérios consideram o uso do Querydsl .
Querydsl suporta JPA / Hibernate, JDO, SQL e Coleções.
Eu sou o mantenedor do Querydsl, então essa resposta é tendenciosa.
fonte
Para mim, os critérios são bastante fáceis de entender e fazer consultas dinâmicas. Mas a falha que eu digo até agora é que ele carrega todas as relações etc, porque temos apenas três tipos de FetchModes, isto é, Select, Proxy e Default e, em todos esses casos, carrega muitos (pode ser que eu esteja errado, se for o caso) estou fora :))
A segunda questão com os Critérios é que ele carrega o objeto completo, ou seja, se eu quiser carregar o EmpName de um funcionário, ele não cria esse instante, ele cria o objeto Employee completo e posso obter o EmpName por causa disso, ele realmente funciona mal em relatórios . onde o HQL apenas carrega (não carrega associação / relações) o que você deseja, para aumentar o desempenho muitas vezes.
Um recurso dos Critérios é que ele protegerá você do SQL Injection por causa de sua geração dinâmica de consultas, onde, no HQL, suas consultas são fixas ou parametrizadas, portanto, não são seguras do SQL Injection.
Além disso, se você escrever HQL em seus arquivos aspx.cs, estará fortemente associado ao seu DAL.
No geral, minha conclusão é que existem lugares em que você não pode viver sem o HQL como relatórios, portanto, use-os, caso contrário, os critérios são mais fáceis de gerenciar.
fonte
API de critérios
A API de critérios é mais adequada para consultas geradas dinamicamente. Portanto, se você deseja adicionar filtros da cláusula WHERE, cláusulas JOIN ou variar a cláusula ORDER BY ou as colunas de projeção, a API Criteria pode ajudá-lo a gerar a consulta dinamicamente de uma maneira que também evite ataques de injeção SQL .
Por outro lado, as consultas de Critérios são menos expressivas e podem até levar a consultas SQL muito complicadas e ineficientes, conforme explicado neste artigo .
JPQL e HQL
JPQL é a linguagem de consulta de entidade padrão do JPA, enquanto o HQL estende o JPQL e adiciona alguns recursos específicos do Hibernate.
JPQL e HQL são muito expressivos e se assemelham a SQL. Diferentemente da Criteria API, o JPQL e o HQL facilitam a previsão da consulta SQL subjacente gerada pelo provedor JPA. Também é muito mais fácil revisar as consultas HQL de uma pessoa do que as de critério.
Vale a pena notar que selecionar entidades com JPQL ou API de critérios faz sentido se você precisar modificá-las. Caso contrário, uma projeção DTO é uma escolha muito melhor.
Conclusão
Se você não precisar alterar a estrutura de consulta da entidade, use JPQL ou HQL. Se você precisar alterar os critérios de filtragem ou classificação ou alterar a projeção, use a API de critérios.
No entanto, apenas porque você está usando JPA ou Hibernate, isso não significa que você não deve usar SQL nativo. As consultas SQL são muito úteis e a API JPQL e Criteria não substitui o SQL. Confira este artigo para obter mais detalhes sobre este tópico.
fonte
Para mim, a maior vitória em Critérios é a API de Exemplo, onde você pode passar um objeto e o hibernate criará uma consulta com base nessas propriedades do objeto.
Além disso, a API de critérios tem suas peculiaridades (acredito que a equipe de hibernação está reformulando a API), como:
Costumo usar o HQL quando quero consultas semelhantes ao sql (excluir de Usuários em que status = 'bloqueado') e costumo usar critérios quando não quero usar o acréscimo de cadeias.
Outra vantagem do HQL é que você pode definir todas as suas consultas com antecedência e até externalizá-las para um arquivo ou mais.
fonte
A API de critério fornece um recurso distinto que nem o SQL nem o HQL fornecem. ie permite a verificação do tempo de compilação de uma consulta.
fonte
Usamos principalmente Critérios em nosso aplicativo no início, mas depois ele foi substituído pelo HQL devido a problemas de desempenho.
Principalmente, estamos usando consultas muito complexas com várias junções, o que leva a várias consultas nos Critérios, mas é muito otimizado no HQL.
O caso é que usamos apenas várias propriedades em objetos específicos e não objetos completos. Com Critérios, o problema também era concatenação de cadeias.
Digamos que, se você precisar exibir o nome e o sobrenome do usuário no HQL, é bastante fácil,
(name || ' ' || surname)
mas no Crteria isso não é possível.Para superar isso, usamos o ResultTransormers, onde havia métodos em que essa concatenação foi implementada para obter o resultado necessário.
Hoje, usamos principalmente o HQL assim:
portanto, no nosso caso, os registros retornados são mapas das propriedades necessárias.
fonte
fonte
fonte
CriteriaUpdate<T>
eCriteriaDelete<T>
para referência.Consulta de critérios para dinamicamente podemos construir consulta com base em nossas entradas .. No caso de consulta Hql é a consulta estática, uma vez que construímos, não podemos alterar a estrutura da consulta.
fonte
Não quero chutar um cavalo morto aqui, mas é importante mencionar que as consultas de critérios agora estão obsoletas. Use HQL.
fonte
Também prefiro Consultas de critério para consultas dinâmicas. Mas eu prefiro o hql para consultas de exclusão, por exemplo, se excluir todos os registros da tabela filho para o ID pai 'xyz', é facilmente alcançado pelo HQL, mas, para os critérios da API, primeiro devemos disparar n número de consultas de exclusão onde n é o número de filhos registros de tabela.
fonte
A maioria das respostas aqui são enganosas e mencionam que
Criteria Queries
são mais lentas queHQL
, o que na verdade não é o caso.Se você se aprofundar e executar alguns testes, verá que as Consultas de Critérios têm um desempenho muito melhor que o HQL comum .
E também com a Consulta de Critérios, você obtém o controle Orientado a Objetos, que não existe no HQL .
Para mais informações, leia esta resposta aqui .
fonte
Existe outro caminho. Acabei criando um analisador HQL baseado na sintaxe original do hibernate, para analisar primeiro o HQL, para injetar dinamicamente parâmetros dinâmicos ou adicionar automaticamente alguns filtros comuns para as consultas HQL. Funciona muito bem!
fonte
Este post é bastante antigo. A maioria das respostas fala sobre os critérios do Hibernate, não sobre os critérios da JPA. O JPA 2.1 adicionou CriteriaDelete / CriteriaUpdate e EntityGraph que controla o que exatamente buscar. A API de critérios é melhor, pois Java é OO. É por isso que o JPA é criado. Quando o JPQL é compilado, ele será traduzido para a árvore AST (modelo OO) antes de traduzido para o SQL.
fonte
O HQL pode causar problemas de segurança , como injeção de SQL.
fonte