La recherche dans cet article se concentre principalement sur le mécanisme du cache d'hibernate, comme suit.
Student.java:
classe publique Student {/ * Student ID * / private int id; / * nom d'étudiant * / nom de chaîne privée; / * relation entre les étudiants et les classes de classe * / classes privées; // omettre les méthodes de setter et de getter}Classes.java:
Classes de classe publiques {/ * class Id * / private int id; / * Nom de classe * / Nom de chaîne privée; / * Relation entre la classe et les étudiants * / ensemble privé <Student> Étudiants; // omettre les méthodes de setter et de getter}Student.hbm.xml:
<? xml version = "1.0"?> <! Doctype Hibernate-Mapping public "- // Hibernate / Hibernate Mapping Dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <HiberNate-Mapping package = "com.lixue.ban"> <classe = "Étudiant =" Étudiant = "Étudiant =" Package = "Com.lixue.ban" table = "t_student"> <id name = "id"> <générateur // id> <! - Map Properties normales -> <propriété name = "name" /> <! - MATTO-TO-ONE MAPPING, Ajoutez une clé étrangère à la fin multiple -> <high-to-one name = "Classes" column = "CASSID" /> </ class> </ Hibernate-Mapping>
Classes.hbm.xml:
<? xml version = "1.0"?> <! Doctype Hibernate-Mapping public "- // Hibernate / Hibernate Mapping Dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <Hibernate-Mapping package = "com.lixue.ban"> <! <class name = "classes" table = "t_classes" lazy = "false"> <id name = "id"> <générateur / générateur /> </ id> <propriété name = "name" /> <! - un-à-mapping, inverse = "true" signifie remettre la relation à le homologue -> <set name = "Students" inverse = "true"> <key Colun </set> </ class> </ hibernate-mapping>
La période de déclaration du cache de premier niveau est très courte et le cycle de vie de la session est cohérent. Le cache de premier niveau est également appelé cache au niveau de la session ou cache au niveau des trucs. Le cache de premier niveau est l'objet de cache et ne peut pas cache.
Méthode de test (utilisez la requête de charge () deux fois dans la même session):
/ * Après l'avoir retiré, il sera placé dans le cache, et la deuxième fois qu'il le récupérera, il sera directement récupéré du cache * / étudiant étudiant = (étudiant) Session.load (Student.class, 1); System.out.println ("Student.Name =" + Student.getName ()); / * Aucune instruction de requête n'est publiée, le chargement utilise le cache * / étudiant = (étudiant) session.load (Student.class, 1); System.out.println ("Student.Name =" + Student.getName ());Remarque: nous constaterons que lorsque nous interrogeons pour la première fois, les résultats trouvés seront placés en session, au cache et au cache de niveau un. Lorsque j'obtiens la valeur à temps après chargement () la deuxième fois, je n'ai pas émis de instruction pour l'interroger dans la base de données, mais j'ai récupéré directement la valeur du cache (il doit être dans la même session).
Méthode de test deux (dans la même session):
Étudiant étudiant = nouveau étudiant (); Student.SetName ("Zhang San"); Sérialisable id = session.save (étudiant); Student = (Student) Session.Load (Student.class, ID); // L'énoncé de requête ne sera pas publié car SAVE prend en charge Cache System.out.println ("Student.Name =" + Student.GetName ());Remarque: La méthode SAVE () est appelée et Load () est utilisée pour charger l'objet, puis l'attribut de nom est réellement obtenu, mais aucune instruction n'est publiée pour interroger la base de données. Parce que la méthode Save () prend également en charge le cache.
Testez l'ajout de grands lots de données:
public void testCache7 () {session session = null; essayez {session = hibernateutils.getSession (); session.begintransaction (); pour (int i = 0; i <100; i ++) {étudiant étudiant = new student (); Student.SetName ("Zhang San" + i); Session.Save (étudiant); // Mette à jour tous les 20 éléments si (i% 20 == 0) {// effacer le cache, et après avoir appelé Flush, les données seront enregistrées dans la base de données session.flush (); // effacer le contenu en cache Session.Clear (); }} session.getTransaction (). commit (); } catch (exception e) {e.printStackTrace (); session.getTransaction (). Rollback (); } enfin {hibernateUtils.closeSession (session); }} Note:
1. Parce que la méthode Save () prend en charge le cache, il y a un problème. Si je veux économiser 10 millions de données en même temps, il y a 10 millions d'objets de cache dans le cache, ce qui est susceptible de provoquer un débordement. Par conséquent, Hibernate ne prend pas en charge le fonctionnement de mise à jour des données à grande échelle, mais nous pouvons également gérer ce problème de manière très flexible, comme la nettoyage du cache toutes les 20 données à l'aide d'une boucle.
2. Enregistrer, mettre à jour, sauvegarder, charger, obtenir, liste, itérer, les méthodes de verrouillage mettront des objets dans le cache de premier niveau. Le cache de premier niveau ne peut pas contrôler le nombre de caches, vous devez donc faire attention à la possibilité de débordement de mémoire lors de l'exploitation des données en gros lots; Vous pouvez utiliser l'expulsion et effacer la méthode pour effacer le contenu dans le cache.
Le cache secondaire est également appelé cache au niveau du processus ou cache de niveau SessionFactory, et le cache secondaire peut être partagé par tous les caches de session. Le cycle de vie du cache secondaire est le même que celui de SessionFactory. Le SessionFactory peut gérer le cache secondaire. Le principe du cache secondaire est utilisé lorsque la lecture est beaucoup plus grand que l'écriture. Le cache secondaire est principalement utilisé pour mettre en cache des objets d'entité.
1. Copiez le fichier ehcahe.xml dans le répertoire SRC.
2. Ajoutez le fournisseur de produits Cache au fichier hibernate.cfg.xml, comme suit:
<propriété name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </ propriété>
3. Activer le cache de niveau 2 (ne peut pas afficher le démarrage, car la valeur par défaut est activée), comme suit:
<propriété name = "hibernate.cache.use_second_level_cache"> true </ propriété>
4. Spécifiez les classes d'entités utilisent le cache de niveau 2.
5. Importez le package de pot d'interface utilisé par le cache: lib/optional/ehcache/ehcache-core-2.4.3.jar
Contenu du fichier ehcache.xml:
<defaultCache maxElementsInMemory = "10000" eternal = "false" TimeToidleSonds = "120" TIMETOLIVESECONDS = "120" overflowtodisk = "true" />
Note:
1.MaxElementsInMemory représente les objets les plus stockés du cache.
2. Eternal indique s'il expirera jamais (le mettre sur False est plus pratique. Si elle est vraie, elle n'expirera jamais, alors les attributs suivants sont dénués de sens).
3.LemetOidleScods indique combien de temps un objet n'a pas été accessible après la première fois qu'il a été effacé.
4. TIMETOLIVESECODS représente le temps d'inventaire d'un objet.
5. OverflowTodisk est vrai, ce qui signifie que le nombre dans le cache dépasse le nombre spécifié par MaxElementsInMemory et est stocké sur le disque.
Spécifiez le chemin du disque enregistré sur le débordement:
<diskstore path = "java.io.tmpdir" />
Remarque: ce chemin peut être modifié.
Méthode de test (la prémisse du cache de niveau 1 est qu'elle doit être dans la même session. Nous utilisons maintenant le cache de niveau 2 pour voir s'il y a un cache en deux sessions différentes):
public void testCache1 () {session session = null; try {session = hibernateutils.getsesse (); session.begintransaction (); étudiant étudiant = (étudiant) session.load (student.class, 1); System.out.println ("Student.Name =" + Student.getName ()); session.getTransaction (). {e.printStackTrace (); session.getTransaction (). Rollback ();} enfin {hibernateutils.closeSession (session);} try {session = HiberNateUtils.getSession (); session.begintransaction (); étudiant étudiant = (étudiant) Session.Load (Student.class, 1); // la déclaration de Query ne sera pas publiée parce que la configuration de la session peut être publiée parce que le cache de deuxième Partagez les données dans le cache secondaire.// le cache secondaire est un système de cache de processus. {Hibernateutils.closeSession (session);}}Remarque: Si le cache secondaire est configuré, nous constaterons que même si la première session est fermée et qu'une autre session est activée pour charger des données, elle ne publiera pas une instruction pour interroger les données de la base de données, car le cache secondaire est configuré, il est partagé par toute la sessionFactory.
Désactiver le cache de niveau 2 pour implémenter l'ajout de grands lots de données:
public void testCache5 () {session session = null; essayez {session = hibernateutils.getSession (); session.begintransaction (); // le cache d'abord en ligne et l'interaction de cache secondaire sont interdits session.setcachemode (cachemode.ignore); pour (int i = 0; i <100; i ++) {étudiant étudiant = new student (); Student.SetName ("Zhang San" + I); Session.Save (étudiant); // Mette à jour tous les 20 éléments if (i% 20 == 0) {session.flush (); // Clear Cached Content Session.Clear (); }} session.getTransaction (). commit (); } catch (exception e) {e.printStackTrace (); session.getTransaction (). Rollback (); } enfin {hibernateUtils.closeSession (session); }}Remarque: session.flush () signifie effacer le cache de premier niveau, mais nous avons recommencé le cache de deuxième niveau, et après SAVing (), il le sauve également dans le cache de deuxième niveau, mais il y a toujours un trop-plein causé par un cache excessif. Donc, dans ce cas, nous devons désactiver le cache secondaire: session.setCachemode (cachemode.ignore);
Cache de requête: le cache de premier niveau et le cache de cache de deuxième niveau du cache à deux objets d'entité de cache, mais parfois nous espérons obtenir certains attributs et n'accédez pas fréquemment à la base de données, mais l'obtenons à partir du cache. Pour le moment, nous pouvons utiliser le cache de requête. De plus, les ensembles de résultats de cache de requête pour les objets entités mettra en cache ID. Le cycle de vie du cache de requête est modifié. Lorsque le tableau associé est modifié, le cycle de déclaration du cache de requête se termine, ce qui n'a rien à voir avec le cycle de vie de la session.
1. Modifiez le fichier hibernate.cfg.xml pour activer le cache de requête. Si false est par défaut, il n'est pas activé. Il doit être défini comme suit:
<propriété name = "hibernate.cache.use_query_cache"> true </ propriété>
2. Doit être activé dans le programme, tel que:
query.setCachable (true)
Méthode de test:
public void testCache2 () {session session = null; try {session = hibernateutils.getsesse (); session.begintransaction (); list names = session.createery ("select s.name from student s") .setCacheable (true) .list (); for (int i = 0; i <noms.size (); i ++) {String name = (String) names.get (i); System.out.println (name);} session.getTransaction (). Commit ();} catch (exception e) {e.printStackTrace (); session.getTransaction (). Rollback ();} {HibernateUtils.closeSession(session);}System.out.println("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- .List (); pour (int i = 0; i <names.size (); i ++) {String name = (string) names.get (i); system.out.println (name);} session.getTransaction (). commit.getTransaction (). {Hibernateutils.closeSession (session);}}Remarque: Dans le code ci-dessus, nous désactivons le cache secondaire, activons le cache de requête, puis interrogeons les propriétés normales. Exécutez le code de test et nous pouvons constater que lors de la première session, la première requête publie une instruction, puis ferme la session, puis la demande dans la deuxième session. Nous constatons que la requête de la deuxième session n'émet pas de déclaration, ce qui signifie que le cache de requête n'a rien à voir avec le cycle de vie de la session.
Configuration du cache de hibernate.cfg.xml:
<! - Définissez l'interface d'implémentation pour spécifier le cache secondaire -> <propriété name = "hibernate.cache.region.factory_class"> org.hibernate.cache.ehcacheRegionFactory </ propriété> <! - Définissez le fichier de configuration utilisé pour le cache secondaire -> <propriété name = "net.sf.ehcache.configurationResourceName"> / ehcache.xml </ propriété> <! - Définissez le cache à l'aide de la query -> <propriété name = "Hibernate.cache.use_query_cache"> true </ property> <! - Chargez le fichier de mappage de la relation de l'objet -> <mapping ressource = "com / lixue / bean / class. <mapping ressource = "com / lixue / bean / student.hbm.xml" /> <! - Le fichier de mappage des ressources (c'est-à-dire le fichier de mappage d'entité) doit être introduit avant de configurer une classe d'entité en utilisant le cache de niveau 2 -> <class-cache usage = "read-only" />
Ce qui précède est tout le contenu de cet article sur l'analyse du code des exemples de mécanisme de cache d'hibernate, j'espère que cela sera utile à tout le monde. Les amis intéressés peuvent continuer à se référer à d'autres sujets connexes sur ce site. S'il y a des lacunes, veuillez laisser un message pour le signaler. Merci vos amis pour votre soutien pour ce site!