Qu'est-ce que le chargement paresseux en Java ? Je ne comprends pas le processus. Quelqu'un peut-il m'aider à comprendre le processus de lazy loading ?
Il est également possible d'utiliser Hibernate.initialize(parent.getChildren()).
Qu'est-ce que le chargement paresseux en Java ? Je ne comprends pas le processus. Quelqu'un peut-il m'aider à comprendre le processus de lazy loading ?
Supposons que vous ayez un parent et que ce parent ait une collection d'enfants. Hibernate peut maintenant "charger paresseusement" les enfants, ce qui signifie qu'il ne charge pas réellement tous les enfants lors du chargement du parent. Au lieu de cela, il les charge lorsqu'on lui demande de le faire. Vous pouvez le demander explicitement ou, ce qui est beaucoup plus courant, Hibernate les chargera automatiquement lorsque vous essayez d'accéder à un enfant.
Le chargement paresseux peut contribuer à améliorer les performances de manière significative, car souvent vous n'aurez pas besoin des enfants et ils ne seront donc pas chargés.
Attention également au problème n+1. Hibernate ne chargera pas réellement tous les enfants lorsque vous accédez à la collection. Au lieu de cela, il chargera chaque enfant individuellement. Lors de l'itération sur la collection, cela entraîne une requête pour chaque enfant. Pour éviter cela, vous pouvez inciter Hibernate à charger tous les enfants simultanément, par exemple en appelant parent.getChildren().size().
L'affirmation "lorsque vous accédez à la collection ... il chargera chaque enfant individuellement" est en fait complètement inexacte. C'est en fait exactement le contraire. Toute déréférence de parent.getChildren() entraînera le chargement par Hibernate de tous les enfants de la collection en une seule requête de la base de données. À moins que vous n'utilisiez l'indice de chargement paresseux très spécial "extra lazy". Ou à moins que vous ne mettiez la collection en cache de second niveau et que les enfants associés ne soient pas également mis en cache.
"Chargement paresseux" signifie qu'une entité sera chargée uniquement quand vous en fait accède à l'entité pour le premièrement temps.
Le site motif c'est comme ça :
public Entity getEntity() {
if (entity == null) {
entity = loadEntity();
}
return entity;
}
Cela permet d'économiser le coût du préchargement/pré-remplissage. tous les entités d'un grand ensemble de données au préalable alors qu'après tout, vous n'avez pas vraiment besoin de tous d'entre eux.
Dans Hibernate, vous pouvez configurer le chargement paresseux d'une collection d'entités enfant. L'adresse réel Le chargement paresseux est alors effectué à l'intérieur des méthodes de l'objet PersistentSet
qu'Hibernate utilise "sous le capot" pour affecter la collection d'entités en tant que Set
.
Par exemple
public class Parent {
private Set<Child> children;
public Set<Child> getChildren() {
return children;
}
}
.
public void doSomething() {
Set<Child> children = parent.getChildren(); // Still contains nothing.
// Whenever you call one of the following (indirectly),
// Hibernate will start to actually load and fill the set.
children.size();
children.iterator();
}
Martin Fowler définit le Chargement paresseux motif dans Modèles d'architecture d'application d'entreprise comme tel :
Un objet qui ne contient pas toutes les données dont vous avez besoin mais qui sait comment les obtenir.
Ainsi, lors du chargement d'un objet donné, l'idée est de ne pas charge rapide le(s) objet(s) associé(s) que vous ne pouvez pas utiliser immédiatement afin d'économiser le coût des performances associées. Au contraire, le ou les objets associés ne seront chargés que lorsqu'ils seront utilisés.
Il ne s'agit pas d'un motif spécifique à l'accès aux données et à Hibernate, mais il est particulièrement utile dans ces domaines. Hibernate prend en charge le chargement paresseux des associations un-à-plusieurs et des associations à point unique (un-à-un et plusieurs-à-un) également sous certaines conditions. L'interaction paresseuse est abordée plus en détail dans Chapitre 19 de la documentation de référence d'Hibernate 3.0.
Par défaut, le chargement paresseux est vrai. Le chargement paresseux signifie que lorsque la requête de sélection est exécutée, elle ne touchera pas la base de données. Il attendra la fonction getter, c'est à dire que lorsque nous en aurons besoin, il ira chercher dans la base de données. Par exemple : Vous êtes un parent qui a un enfant avec beaucoup de jouets. Mais le problème actuel est que chaque fois que vous l'appelez (nous supposons que vous avez un garçon), il vient à vous avec tous ses jouets aussi. C'est un problème car vous ne voulez pas qu'il se promène avec ses jouets tout le temps. Alors, en tant que parent rationnel, vous allez de l'avant et définissez les jouets de l'enfant comme paresseux. Maintenant, chaque fois que vous l'appelez, il vient vous voir sans ses jouets.
Le Lazy fetching décide de charger les objets enfants pendant le chargement de l'objet parent. Vous devez effectuer ce paramétrage dans le fichier de mapping hibernate de la classe parent. Lazy = true
(signifie ne pas charger l'enfant) Par défaut, le chargement paresseux des objets enfants est vrai.
Ceci permet de s'assurer que les objets enfants ne sont pas chargés à moins qu'ils ne soient explicitement invoqués dans l'application en appelant getChild()
Dans ce cas, Hibernate lance un nouvel appel à la base de données pour charger l'enfant lorsque l'enfant est chargé. getChild()
est actuellement appelé sur l'objet Parent.
Mais dans certains cas, vous avez besoin de charger les objets enfants lorsque le parent est chargé. Il suffit de mettre lazy=false et Hibernate chargera l'enfant lorsque le parent sera chargé depuis la base de données.
Exemple : Si vous avez une TABLE ? EMPLOYEE mappée à l'objet Employee et contenant un ensemble d'objets Address. Classe parentale : classe Employé, Classe enfant : Classe Adresse
public class Employee {
private Set address = new HashSet(); // contains set of child Address objects
public Set getAddress () {
return address;
}
public void setAddresss(Set address) {
this. address = address;
}
}
Dans le fichier Employee.hbm.xml
<set name="address" inverse="true" cascade="delete" lazy="false">
<key column="a_id" />
<one-to-many class="beans Address"/>
</set>
Dans la configuration ci-dessus. Si lazy="false"
Lorsque vous chargez l'objet Employee, l'objet enfant Address est également chargé et défini par la méthode setAddresss(). Si vous appelez employee.getAdress(), les données chargées reviennent, sans nouvel appel à la base de données.
Si lazy="true"
:- Il s'agit de la configuration par défaut. Si vous ne le mentionnez pas, Hibernate considère que lazy=true. Lorsque vous chargez l'objet Employee, l'objet enfant Adress n'est pas chargé. Vous avez besoin d'un appel supplémentaire à la base de données pour obtenir des objets d'adresse. Si vous appelez employee.getAdress()
alors la requête de la base de données se déclenche et renvoie les résultats. Nouvel appel à la base de données.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.