O cache da sessão é armazenado com gráficos de objetos inter -relacionados. Por padrão, quando o Hibernate carrega objetos do cliente do banco de dados, todos os objetos de ordem associados são carregados ao mesmo tempo. Tomando as classes de clientes e pedidos como exemplos, suponha que a chave estrangeira do cliente_id da tabela de pedidos possa ser nula
O método Session的find() é usado para recuperar todos os objetos do cliente no banco de dados:
List customerLists=session.find("from Customer as c");
Ao executar o método find() acima, o Hibernate primeiro consultará todos os registros na tabela de clientes e, em seguida, consulte a tabela de pedidos com relacionamentos de referência com base no ID de cada registro. Hibernate executará as seguintes instruções selecionadas por sua vez:
selecione * dos clientes;
Selecione * FROM PEDIDOS ONDE Customer_Id = 1;
Selecione * FROM PEDIDOS ONDE Customer_Id = 2;
Selecione * FROM PEDIDOS ONDE Customer_Id = 3;
Selecione * FROM PEDIDOS ONDE Customer_Id = 4;
Através das 5 instruções de seleção acima, o Hibernate finalmente carrega 4 objetos de clientes e 5 objetos de pedidos, formando um gráfico de objetos associado na memória.
O Hibernate usa a política de pesquisa padrão agora ao recuperar objetos de ordem associados ao cliente. Existem duas grandes deficiências nesta estratégia de pesquisa:
(1) O número de instruções selecionadas é muito grande e o acesso frequente ao banco de dados afetará o desempenho da recuperação. Se você precisar consultar N Objetos do Cliente, N+1 selecione a instrução de consulta deve ser executada. Este é o problema clássico de consulta N+1 clássico. Esta estratégia de pesquisa não utiliza a função de consulta de conexão do SQL. Por exemplo, as 5 instruções de seleção acima podem ser completamente concluídas pela seguinte instrução 1 Selecionar:
Selecione * dos clientes que deixam os pedidos de junção externa
em clientes.id = orders.customer_id
A instrução SELECT acima usa a função de consulta externa esquerda do SQL, que pode consultar todos os registros da tabela de clientes e registros da tabela de pedidos correspondentes em uma instrução SELECT.
(2) Em situações em que a lógica do aplicativo só precisa acessar objetos do cliente, mas não solicitar objetos, o carregamento de objetos do pedido é completamente desnecessário. Esses objetos de ordem desnecessários desperdiçam muito espaço de memória.
Para resolver os problemas acima, o Hibernate fornece duas outras estratégias de pesquisa: uma estratégia de pesquisa tardia e uma estratégia de pesquisa de conexão com esquerda urgente. A estratégia de recuperação tardia pode evitar o carregamento redundante de objetos associados que o aplicativo não precisa acessar. A estratégia urgente de recuperação de conexão externa esquerda faz pleno uso da função de consulta de conexão externa do SQL e pode reduzir o número de instruções selecionadas.
Os problemas de desempenho devem ser considerados ao acessar bancos de dados. Depois de definir o relacionamento de 1 para muitos, o lendário problema de N +1 ocorrerá na consulta.
1) 1 Para muitos, em 1 quadrado, N objetos podem ser encontrados; em seguida, o conjunto associado a N objetos precisa ser retirado, para que a consulta SQL original se torne n +1
2) Muitos a 1. Se você consultar os objetos M em várias partes, o objeto de 1 partido correspondente aos objetos M será retirado e também se tornará M+1.
1) preguiçoso = verdadeiro, o Hibernate3 já inadimpleiu para preguiçoso = true; Quando preguiçoso = verdadeiro, o objeto associado não será consultado imediatamente. A ação da consulta ocorrerá apenas quando o objeto associado (acessando seus atributos, campos não IDs).
2) cache de nível 2. Quando o objeto é muito menos atualizado, excluído e adicionado que as consultas, a aplicação do cache de nível 2 não terá medo de N +1, porque mesmo que a primeira consulta seja lenta, o acerto do cache será muito rápido posteriormente.
Soluções diferentes e idéias diferentes, mas a segunda usa N +1 novamente.
3) Claro que você também pode definir fetch=join(annotation : @ManyToOne() @Fetch(FetchMode.JOIN))
O exposto acima é tudo sobre a breve discussão deste artigo sobre a edição do Hibernate n+1, e espero que seja útil para todos. Amigos interessados podem continuar se referindo a outros tópicos relacionados neste site. Se houver alguma falha, deixe uma mensagem para apontá -la. Obrigado amigos pelo seu apoio para este site!