Pergunta

Quais são os prós e contras do uso critérios ou HQL ? A API Criteria é uma maneira agradável orientada a objetos para expressar consultas em hibernação, mas às vezes Critérios consultas são mais difíceis de entender / build do que 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?

Foi útil?

Solução

Eu prefiro principalmente Critérios Consultas para consultas dinâmicas. Por exemplo, é muito mais fácil de adicionar um pouco de ordenação de forma dinâmica ou deixar algumas partes (por exemplo, restrições) para fora, dependendo de algum parâmetro.

Por outro lado eu estou usando HQL para estático e consultas complexas, porque é muito mais fácil de entender / ler HQL. Além disso, HQL é um pouco mais potente, penso eu, por exemplo, para diferentes tipos de junção.

Outras dicas

Há uma diferença em termos de desempenho entre HQL e criteriaQuery, toda vez que você disparar uma consulta usando criteriaQuery, ele cria um novo apelido para o nome da tabela que não reflete no último esconderijo consultado para qualquer DB. Isto leva a uma sobrecarga de compilação do SQL gerado, tendo mais tempo para executar.

Em relação buscar estratégias [http://www.hibernate.org/315.html]

  • Critérios aspectos as configurações preguiça em seus mapeamentos e garante que o que você quer carregado é carregado. Isto significa que uma Critérios consulta pode resultar em vários SQL SELECT imediatas para buscar o subgrafo com todas as associações mapeadas não-preguiçosos e coleções. Se você quer mudar o "como" e até mesmo "o que", o uso setFetchMode () para ativar ou desativar a junção externa buscar para uma coleção particular ou associação. Critérios consultas também respeitar completamente a estratégia de busca (se juntar vs select vs subselect).
  • HQL respeita as configurações de preguiça em seus mapeamentos e garante que o que você quer carregado é carregado. Este meio de consulta um HQL pode resultar em várias SQL SELECT imediatas para buscar o subgrafo com todas as associações mapeadas não-preguiçosos e coleções. Se você quer mudar o "como" e até mesmo "o que", use LEFT JOIN FETCH para permitir recuperação da união exterior para uma coleção particular ou anulável associação muitos-para-um ou um-para-um, ou join fetch para ativar junção interna buscar por uma associação não-nulo muitos-para-um ou um-para-um. consultas HQL não respeitam qualquer fetch = "join" definido no documento de mapeamento.

Critérios é uma API orientada a objeto, enquanto HQL significa concatenação. Isso significa que todos os benefícios do objeto-orientedness se por:

  1. All ser o resto igual, a versão OO é um pouco menos propenso a erros. Qualquer cadeia de idade poderia ter anexado na consulta HQL, enquanto que apenas válidos Critérios objetos podem fazê-lo em uma árvore Critérios. Efetivamente, as classes critérios são mais restritos.
  2. Com auto-complete, o OO é mais visível (e, portanto, mais fácil de usar, pelo menos para mim). Você não necessariamente precisa se lembrar que partes da consulta ir para onde; o IDE pode ajudá-lo
  3. Você também não precisa se lembrar os detalhes da sintaxe (como símbolos que ir onde). Tudo que você precisa saber é como chamar métodos e criar objetos.

Desde HQL é muito parecido com SQL (que a maioria devs sabem muito bem já), então estes "não tem que se lembrar" argumentos não levar tanto peso. Se HQL era mais diferente, então isso seria mais importatnt.

Eu costumo usar critérios quando eu não sei o que as entradas serão utilizados em que pedaços de dados. Como em um formulário de pesquisa onde o usuário pode entrar em qualquer de 1 a 50 itens e eu não sei o que eles vão estar procurando. É muito fácil simplesmente acrescentar mais com os critérios como eu passar por verificação de que o usuário está procurando. Eu acho que seria um pouco mais problemático para colocar uma consulta HQL em que circunstância. HQL é ótimo embora quando eu sei exatamente o que quero.

HQL é muito mais fácil de ler, mais fácil de depurar usando ferramentas como o plugin Eclipse Hibernate, e mais fácil de log. Critérios consultas são melhores para a construção de consultas dinâmicas, onde uma grande parte do comportamento é determinado em tempo de execução. Se você não sabe SQL, eu poderia entender utilizando critérios de consultas, mas no geral eu prefiro HQL se eu sei o que quero inicial.

Os critérios são a única maneira de especificar pesquisas de chave naturais que tiram proveito da otimização especial no cache de segundo nível consulta. não HQL não tem qualquer maneira de especificar a dica necessário.

Você pode encontrar mais algumas informações aqui:

Criteria API é um dos bons conceito de Hibernate. de acordo com meu ponto de vista são o ponto de alguns pelo qual nós podemos fazer a diferença entre HQL e Critérios Api

  1. HQL é realizar ambas as operações selecionados e não-selecionados sobre os dados, mas Critérios é apenas para selecionar os dados, não podemos executar operações não-selecionados a partir de critérios.
  2. HQL é adequado para execução estática Consultas, onde, como Criteria é adequado para a execução de consultas dinâmicas
  3. HQL não suporta pagination conceito, mas podemos conseguir a paginação com critérios.
  4. Os critérios utilizados para levar mais tempo para executar do que HQL.
  5. com os critérios que são seguros com SQL Injection por causa de sua geração de consulta dinâmica, mas em HQL como suas consultas são fixos ou parametrizada, não há seguro contra SQL Injection

Para mim Criteria é um muito fácil de entender e fazer consultas dinâmicas. Mas a falha i dizer até agora é que ele carrega todas as relações muitos-um etc, porque temos apenas três tipos de FetchModes ou seja, Select, Proxy e padrão e em todos estes casos, carrega muitos-um (pode ser que eu estou errado, se assim ajuda me out:))

2ª emissão com critérios é que ele carrega ou seja objeto completa se eu quiser EmpName carga apenas de um empregado que não vai vir para cima com este Insted que vir para cima com objeto Employee completa e eu posso obter EmpName dele devido a este realmente mau trabalho em relatar . onde como HQL apenas carga (associação de carga did't / relações) que u quer assim aumentar o desempenho muitas vezes.

Uma das características da Criteria é que ele vai u salvo de SQL Injection por causa de sua geração consulta dinâmica onde, como em HQL como ur consultas são fixos ou parametrizado por isso não estão a salvo de injeção SQL.

Além disso, se você escrever HQL em ur arquivos aspx, então você está intimamente ligado com ur DAL.

No geral a minha conclusão é que há lugares onde u não pode viver sem HQL como relatórios para usá-los Critérios o resto é mais fácil de gerir.

Para usar o melhor dos dois mundos, a expressividade e concisão de HQL e a natureza dinâmica da Criteria considerar o uso Querydsl .

Querydsl suporta JPA / Hibernate, JDO, SQL e coleções.

Eu sou o mantenedor do Querydsl, então esta resposta é tendenciosa.

Para mim, a maior vitória sobre Critérios é o exemplo da API, onde você pode passar um objeto eo Hibernate vai criar uma consulta com base nessas propriedades do objeto.

Além disso, a API critérios tem as suas peculiaridades (creio que a equipe de hibernação é refazer o API), como:

  • A criteria.createAlias ??( "obj") forças participar de um interior em vez de uma possível junção externa
  • você não pode criar o mesmo alias duas vezes
  • algumas cláusulas SQL têm nenhuma contrapartida critérios simples (como um subselect)
  • etc.

I tendem a usar HQL quando eu quero consultas semelhantes a SQL (excluir usuários onde status = 'bloqueados'), e eu tendem a usar critérios quando eu não quero acrescentando seqüência de uso.

Outra vantagem do HQL é que você pode definir todas as suas dúvidas antes da mão, e até mesmo à sua externalização para um arquivo ou assim.

Criteria API é mais adequado para consultas geradas dinamicamente quando os filtros de consulta são aplicadas dinamicamente em tempo de execução. Portanto, para evitar SQL ataques de injeção ao construir consultas dinâmicas, Criteria API é uma escolha muito boa.

Critérios consultas são menos expressivas e você pode facilmente acabar-se com um muito complicado e ineficiente SQL gerado consulta . uma vez que se juntou a um grande aplicativo corporativo, onde Criteria API foi o método de consulta padrão e nem mesmo extensa code-revisão poderia superar o horror de não saber o consultas SQL que íamos acabar com.

JPQL ou HQL é muito mais expressivo, e é muito mais fácil prever a consulta SQL gerado associado. É também muito mais fácil de consultas HQL revisão de um do que Critérios queridos.

A maioria dos casos de uso entidade consultas não requerem dinâmica onde cláusulas para que você possa implementar a maioria das consultas com JPQL deixando Critérios para os mais dinâmicos.

É importante notar que as entidades Seleccionar com JPQL ou Criteria API faz sentido se você precisa modificá-los. Caso contrário, uma projecção DTO executa melhor. Confira este artigo para mais informações .

Criteria API fornecer uma característica distinta que nem SQL ou HQL fornece. ie. ele permite que a verificação de tempo de compilação de uma consulta.

Nós usado principalmente Critérios em nossa aplicação no começo, mas depois que ele foi substituído por HQL devido aos problemas de desempenho.
Principalmente nós estamos usando consultas muito complexas com várias associações que leva a várias consultas em critérios, mas é muito otimizado em HQL.
O caso é que nós usamos apenas alguns propeties no objeto específico e objetos não completos. Com Critérios o problema também foi concatenação.
Vamos dizer que se você precisar exibir nome e sobrenome do usuário em HQL é muito fácil (name || ' ' || surname) mas em Crteria isso não é possível.
Para superar isso, ResultTransormers usados, onde havia métodos em que tais concatenação foi implementado para o resultado necessário.
Hoje nós usamos principalmente HQL como esta:

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();

Assim, no nosso caso, os registros retornados são mapas de propriedades necessárias.

  • HQL é realizar ambas as operações selecionados e não-selecionados sobre os dados, mas Critérios é apenas para selecionar os dados, não podemos executar operações não-selecionados a partir de critérios
  • HQL é adequado para execução estática Consultas, onde, como Criteria é adequado para a execução de consultas dinâmicas
  • HQL não suporta o conceito de paginação, mas podemos conseguir a paginação com critérios
  • Os critérios utilizados para levar mais tempo para executar, em seguida, HQL
  • com os critérios que são seguros com SQL Injection por causa de sua geração de consulta dinâmica, mas em HQL como suas consultas são fixos ou parametrizada, não há seguro contra SQL Injection.

fonte

consulta Critérios para dinamicamente podemos construir consulta com base no nosso caso inputs..In de consulta HQL é a consulta estática, uma vez que a construção não podemos mudar a estrutura da consulta.

Eu não quero chutar um cavalo morto aqui, mas é importante mencionar que os critérios consultas são agora obsoletas. Use HQL.

Eu também prefiro Critérios Consultas para consultas dinâmicas. Mas eu prefiro hql para consultas de exclusão, por exemplo, se excluir todos os registros da tabela filho para id pai 'xyz', é facilmente alcançado por HQL, mas por critérios API primeiro temos de disparar n número de consulta de exclusão, onde n é o número de criança registros da tabela.

A maioria das respostas aqui são enganosas e mencionar que Criteria Queries são mais lentos que HQL, que não é realmente o caso.

Se você mergulhar profundamente e realizar alguns testes, você verá Critérios Consultas desempenho muito melhor que HQL regulares .

E também com critérios de consulta você começa Object Oriented controle que não é lá com HQL .

Para obter mais informações, leia esta resposta aqui .

Não há outra maneira. Eu acabei com a criação de um analisador HQL com base na sintaxe originais de hibernação por isso primeiro analisar o HQL então ele parâmetros dinâmicos poderia dinamicamente injetar ou automaticamente adicionando alguns filtros comuns para as consultas HQL. Ele funciona muito bem!

Este post é bastante antigo. A maioria das respostas falar sobre critérios do Hibernate, e não critérios JPA. JPA 2.1 adicionado CriteriaDelete / CriteriaUpdate e EntityGraph que os controles exatamente o que buscar. Critérios API é melhor desde Java é OO. É por isso que JPA é criado. Quando JPQL é compilado, ele será traduzido em árvore AST (modelo OO) antes traduzido para SQL.

HQL pode causar segurança preocupações como injeção de SQL.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top