El caché de la sesión se almacena con gráficos de objetos interrelacionados. De manera predeterminada, cuando Hibernate carga los objetos del cliente de la base de datos, todos los objetos de pedido asociados se cargan al mismo tiempo. Tomar las clases de clientes y pedidos como ejemplos, suponga que la Tabla de órdenes de Customer_ID de la Tabla de pedidos puede ser nula
El método Session的find() se utiliza para recuperar todos los objetos del cliente en la base de datos:
List customerLists=session.find("from Customer as c");
Al ejecutar el método find() anterior, Hibernate primero consultará todos los registros en la tabla de clientes y luego consultará la tabla de pedidos con relaciones de referencia basadas en la ID de cada registro. Hibernate ejecutará las siguientes declaraciones de selección a su vez:
seleccionar * de los clientes;
Seleccione * de los pedidos donde customer_id = 1;
Seleccione * de los pedidos donde customer_id = 2;
Seleccione * de pedidos donde customer_id = 3;
Seleccione * de los pedidos donde customer_id = 4;
A través de las 5 declaraciones de selección anteriores, Hibernate finalmente carga 4 objetos de clientes y 5 objetos de pedido, formando un gráfico de objetos asociado en la memoria.
Hibernate utiliza la política de búsqueda predeterminada ahora al recuperar los objetos de pedido asociados con el cliente. Hay dos deficiencias principales en esta estrategia de búsqueda:
(1) El número de declaraciones seleccionadas es demasiado grande y el acceso frecuente a la base de datos afectará el rendimiento de la recuperación. Si necesita consultar N objetos del cliente, entonces se debe ejecutar la instrucción de consulta N+1. Este es el problema clásico de consulta de selección N+1. Esta estrategia de búsqueda no utiliza la función de consulta de conexión de SQL. Por ejemplo, las 5 declaraciones de selección anteriores se pueden completar completamente mediante la siguiente declaración de selección:
Seleccione * de los clientes órdenes de unión externa de los clientes.
en clientes.id = orders.customer_id
La instrucción SELECT anterior utiliza la función de consulta de unión externa izquierda de SQL, que puede consultar todos los registros de la tabla de clientes y los registros de la tabla de pedidos coincidentes en una instrucción SELECT.
(2) En situaciones en las que la lógica de la aplicación solo necesita acceder a los objetos del cliente pero no a los objetos de orden, cargar objetos de orden es completamente innecesario. Estos objetos de orden innecesario desperdician mucho espacio de memoria.
Para resolver los problemas anteriores, Hibernate proporciona otras dos estrategias de búsqueda: una estrategia de búsqueda retrasada y una estrategia de búsqueda de conexión urgente de izquierda a menos. La estrategia de recuperación tardía puede evitar la carga redundante de objetos asociados a los que la aplicación no necesita acceder. La estrategia urgente de recuperación de conexión externa izquierda hace que el uso completo de la función de consulta de conexión externa de SQL y pueda reducir el número de declaraciones seleccionadas.
Se deben considerar los problemas de rendimiento al acceder a las bases de datos. Después de establecer la relación de 1 a muchos, el legendario problema N +1 ocurrirá en la consulta.
1) 1 a muchos, en 1 cuadrado, se pueden encontrar n objetos, entonces el conjunto asociado con n objetos debe ser sacado, por lo que la consulta SQL original se convierte en n +1
2) Muchos a 1. Si consulta m objetos en múltiples partes, entonces se eliminará el objeto de 1 parte correspondiente a los objetos M, y también se convertirá en m+1.
1) Lazy = True, Hibernate3 ya ha incorporado a Lazy = true; Cuando sea perezoso = verdadero, el objeto asociado no se consultará de inmediato. La acción de consulta solo ocurrirá cuando el objeto asociado (accediendo a sus atributos, campos no ID).
2) Cache de nivel 2. Cuando el objeto está mucho menos actualizado, eliminado y agregado que las consultas, la aplicación del caché de nivel 2 no tendrá miedo de los problemas N +1, porque incluso si la primera consulta es lenta, el golpe de caché será muy rápido después.
Diferentes soluciones e ideas diferentes, pero la segunda simplemente usa N +1 nuevamente.
3) Por supuesto, también puede establecer fetch=join(annotation : @ManyToOne() @Fetch(FetchMode.JOIN))
Lo anterior se trata de la breve discusión de este artículo sobre el número Hibernate N+1, y espero que sea útil para todos. Los amigos interesados pueden continuar referiéndose a otros temas relacionados en este sitio. Si hay alguna deficiencia, deje un mensaje para señalarlo. ¡Gracias amigos por su apoyo para este sitio!