1. Consulta de objeto de entidade
Pergunta de objeto de entidade é a base da consulta HQL. Como linguagem de consulta de objeto, é diferente do SQL durante as operações de consulta. O conteúdo na sequência de consulta deve ser substituído pelo nome da classe e pelo nome do atributo de classe. Este método de consulta é relativamente simples. Contanto que você tenha habilidades SQL, é muito simples usar o HQL. No entanto, existem alguns problemas que precisam receber atenção, ou seja, consultar e obter dados não é o objetivo, e o que precisa ser considerado é como escrever declarações de consulta eficientes, que é o foco da discussão.
1.n+1 problema
(1) Qual é o problema n+1
Quando ouvi esse substantivo pela primeira vez, posso ter dúvidas. Eu nunca ouvi falar do problema n+1 antes. Então, o que isso significa? N+1 refere -se a dados n em uma tabela; portanto, ao obter esses dados N, o comando n+1 SQL será gerado. Esta operação é chamada n+1. Aqui, 1 refere -se à emissão de uma declaração que procura a lista de identificação e N refere -se à emissão de instruções N SQL com base no ID para carregar objetos relacionados. Esse tipo de operação de consulta é muito ineficiente e é frequentemente gerado em iteradores. Ou seja, se convertermos diretamente os resultados da consulta em iteradores, esse problema ocorrerá, como segue:
public void testQuery () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); /*** Haverá um problema n+1. O chamado N+1 valor é emitir n+1 declarações SQL** 1: emitir uma declaração que consulta a lista de identificação** n: Edição n declarações SQL com base no ID e carregue o objeto relevante*/ iterator iter = session.createquery ("do aluno"). while (iter.hasnext ()) {estudante estudante = (aluno) iter.next (); System.out.println (Student.getName ()); } session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}O código de consulta acima causará um problema n+1, porque a consulta é retornada como um iterador, para que uma instrução SQL seja emitida se não for gerada uma vez. Isso depende principalmente do mecanismo de consulta do iterador, que consulta dados do cache. Se os dados não existirem no cache, os dados serão convertidos primeiro em memória; portanto, uma instrução SQL consulta será emitida no momento, portanto, uma instrução SQL será gerada todas as iterações. Este método de escrita é realmente um erro e pode ser resolvido usando outros métodos para otimizar.
(2) Evite o problema n+1
O problema de n+1 ocorre devido ao uso inadequado de iterado. Obviamente, outros métodos podem ser usados para evitar esse problema de n+1. Aqui está um método de lista. A maior diferença entre a lista e a ITERATE é que a lista coloca dados no cache, mas não usa o cache. Por padrão, a lista emitirá instruções SQL sempre. Antes de usar o ITERETE, você pode usar a lista para salvar os dados no banco de dados, para que o ITERATE possa ler no cache ao acessar os dados, evitando a ocorrência de problemas de n+1. O código é o seguinte:
public void testQuery () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); Listar alunos = session.createquery ("do aluno"). Lista (); System.out.println ("------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ Em seguida, nenhuma consulta SQL com base no ID é emitida e os dados no cache são usados diretamente * * Método se houver dados no cache, ele poderá melhorar o desempenho, caso contrário, n+1 problemas ocorrerão */ // você pode usar o alias (ITERTER) (ITERTER = Session.CreatEmery ("Student). System.Println (Student.getName ()); }}O exemplo acima evita o problema N+1, porque após a execução da operação da lista, os dados serão colocados no cache da sessão (cache de primeiro nível). Portanto, ao usar o ITERATE, uma instrução será emitida para consultar a lista de identificação e os dados correspondentes serão carregados no cache de acordo com o ID. Se houver dados que correspondam ao cache, a consulta de instrução SQL com base no ID não será mais emitida e os dados no cache serão usados diretamente. O método de iteração pode melhorar o desempenho se houver dados no cache, caso contrário, n+1 problemas ocorrerão.
2. Consulta de navegação de objetos
Navegação de objeto refere -se à obtenção de dados de outro objeto de acordo com a navegação de atributos do objeto em um objeto. Isso pode simplificar as instruções de consulta e otimizar os métodos de consulta. Se seguirmos nossas idéias habituais, podemos reescrever e escrever um objeto de outra classe para obter a operação de outro objeto, que é mais pesado para comparar a declaração de navegação por objeto.
@Suppresswarnings ({"desmarcado", "RawTypes"}) public void testQuery1 () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); // retorna a lista de atributos do conjunto de resultados, os tipos de tipo de elemento e atributo na classe de entidade são os mesmos alunos da lista = session.CreateQuery ("dos estudantes s onde s.classes.name como '%2%'"). List (); for (iterator item = estudantes.iterator (); it.hasnext ();) {estudante obj = (aluno) ite.next (); System.out.println (obj.getName ()); } session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}A declaração de consulta no exemplo acima usa o método de navegação de objeto. A declaração de consulta é a consulta de informações do objeto do aluno, mas os atributos do objeto a serem comparados vêm do atributo de nome do objeto de classes. No momento, o uso do método de consulta de navegação de objetos melhorará significativamente a eficiência da consulta e otimizará a instrução de consulta. Se fosse um método de consulta comum, um grande número de declarações de conexão pode ser gerado, o que é muito complicado.
2. Consulta nativa do SQL
O valor da consulta nativa é usar as instruções SQL para consultar e obter dados, em vez de usar instruções HQL. Seu método de uso é realmente muito simples, semelhante ao HQL. Você só precisa usar o método CreateSqlQuery para consultar. Na verdade, é semelhante ao método CreateEmery da HQL. O código é o seguinte:
public void testqeury () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); Lista list = session.createsqlquery ("selecione * de t_student"). List (); for (iterator item = list.iterator (); it.hasnext ();) {object [] obj = (object []) ite.next (); System.out.println (obj [0]+","+obj [1]); } session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}O código acima usa o método CreateSqlQuery. A sequência de consulta no método é uma instrução SQL. Ele implementa o método de consulta de string subjacente. A diferença é que o HQL possui outra camada de embalagem e configura as opções de dialeto correspondentes no hibernate.cfg.xml para concluir o mapeamento.
3. Consulta de conexão
As consultas de conexão são frequentemente usadas no SQL para obter uma coleção de vários objetos. Entre eles, os mais usados são a junção interna, a junção à esquerda, a junção direita etc., que se referem à consulta interna de junção, consulta externa esquerda e consulta externa de junção direita. O conteúdo que eles retornam durante a consulta é o produto cartesiano entre as entidades, o conteúdo da consulta e algum conteúdo da tabela esquerda, o conteúdo da consulta e algum conteúdo da tabela direita, e a função de consulta é poderosa. O método de consulta de conexão do HQL e a consulta de conexão do SQL são os mesmos nos resultados da consulta, mas existem pequenas diferenças nas declarações de consulta.
1. Conexão interior
A consulta Intrajoin do HQL pode ser consultada usando a instrução INNER JUNCION OR JONCE, e o conjunto de resultados obtidos é o produto cartesiano. Semelhante à consulta intra-conexão SQL, a consulta de junção do HQL é dividida em dois tipos: explícito e implícito. A consulta exibida refere -se à palavra -chave JUNC na sequência de consultas. A consulta implícita não precisa adicionar ingressar na string.
// conexão interna @suppresswarnings ({"desmarcada", "RawTypes"}) public void testQuery () {session session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); // retorna a lista de atributos do conjunto de resultados, os tipos de tipo de elemento e atributo na classe de entidade são a mesma lista dos alunos = session.CreateQuery ("Select s.name, c.name da junta do aluno s.classes c"). List (); for (iterator item = student.iterator (); it.hasnext ();) {objeto [] obj = (objeto []) ite.next (); System.out.println (obj [0]); } session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}
2. Conexão externa
As conexões externas são divididas na conexão externa esquerda e na consulta externa direita. Os métodos de consulta são semelhantes, mas o resultado da consulta é diferente. Eles são os mesmos que a conexão externa do SQL nos resultados da consulta. A diferença é o método de escrita. O código específico é o seguinte:
@Suppresswarnings ({"desmarcado", "RawTypes"}) public void testQuery () {sessão session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); // retorna a lista de atributos do conjunto de resultados, os tipos de tipo de elemento e atributo na aula de entidade são a mesma lista dos alunos = session.CreateQuery ("Select s.name, c.name do aluno deixado Junção s.classes c"). List (); for (iterator item = student.iterator (); it.hasnext ();) {objeto [] obj = (objeto []) ite.next (); System.out.println (obj [0]); } session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}O código acima usa uma declaração de consulta de junção externa esquerda. O método de consulta externa direita correspondente é semelhante à junção externa esquerda. Basta converter da esquerda para a direita. Os dados da consulta são salvos no objeto List e o conteúdo da consulta pode ser obtido através da lista.
4. Consulta de nomeação externa
Consulta externa nomeada refere -se a escrever instruções de consulta em um arquivo de mapeamento e usar a tag <Query> para definir instruções HQL no arquivo de mapeamento. Dessa forma, as instruções HQL definidas podem realizar a função de configuração da função. Se houver um problema, só precisará modificar a configuração. Se você deseja usar esta instrução SQL, pode usar o método session.getNamedQuery () no programa para obter a sequência de consulta HQL, conforme mostrado no exemplo a seguir.
1. Declaração de consulta externa
O exemplo a seguir demonstra a aplicação de declarações de consulta externa, adicione a tag <Query> ao arquivo de mapeamento, adicione o atributo de nome à tag e adicione a sequência a <! [CDATA []]>, para que a sequência de consulta correspondente possa ser obtida no programa de acordo com o atributo de nome da consulta.
<? xml versão = "1.0"?> <! Doctype hibernate-mapping public "-// Hibernate/hibernate mapeando dtd 3.0 // pt" "http://hibernate.sourceforge.net/hibernate tabela = "t_student"> <id name = "id"> <generator // id> <propriedade name = "name"/> <propriedade name = "createTime"> </property> <!-Adicione uma nova coluna de classes ao aluno de um lado, e o nome da coluna deve ser o mesmo que a lista de classes. </classe> <Nome da Query = "QueryStudent"> <! [CDATA [Selecione S de Students onde S.id <? ]]> </ Query> </hibernate-mapping>
A consulta externa nomeada coloca a declaração de consulta no arquivo de mapeamento, para que possa ser considerado uma sequência de consulta pública. Essa é sua vantagem, para que outros arquivos de programa possam ser obtidos e usados. Além disso, aumenta a conveniência da modificação como uma sequência pública.
2. Aplicação do programa
Após definir declarações de consulta externa, é necessário usá -las no programa. O HQL fornece o método GetNameQuery para obter a sequência de instrução de consulta externa. Um nome de cursor externo precisa ser adicionado a esse método. O HQL consultará o bloco de instrução SQL correspondente com base no nome do cursor, como segue:
// Naming externo Query @suppresswarnings ({"desmarcado", "RawTypes"}) public void testQuery () {Session Session = null; tente {session = hibernateUtils.getSession (); session.BegIntransaction (); Listar alunos = session.getNamedQuery ("QueryStudent"). SetParameter (0, 10) .List (); for (iterator item = estudantes.ite.hasnext ();) {estudante obj = (aluno) ite.next (); System.out.println (obj.getName ()); } session.gettransaction (). Commit (); } catch (Exceção e) {e.printStackTrace (); session.gettransaction (). rollback (); } finalmente {hibernateutils.closhessession (sessão); }}