Cache hibernate
La mise en cache est une question d'optimisation des performances de l'application et elle est située entre l'application et la base de données pour éviter plusieurs accès de base de données et permettre aux applications critiques de performances de mieux fonctionner.
La mise en cache est importante pour l'hibernate, et il adopte un schéma de mise en cache à plusieurs niveaux décrit ci-dessous:
Cache de niveau 1:
Le premier cache de niveau est le cache de session, qui est un cache obligatoire, et toutes les demandes à travers elle doivent être réalisées. Les objets de session sont constamment alimentés par des objets avant de les soumettre à la base de données.
Si plusieurs mises à jour sont émises, Hibernate tente de retarder les mises à jour aussi longtemps que possible pour réduire le nombre d'instructions SQL émises. Si vous fermez la session, tous les objets mis en cache seront perdus, persistants ou mis à jour dans la base de données.
Cache de niveau 2:
Le cache de niveau 2 est facultatif et le cache de niveau 1 qui sera toujours recherché avant toute tentative de trouver le cache de niveau 2 d'un objet. Le cache de deuxième niveau peut être configuré sur une base par classe et par catégorie, principalement responsable des objets mis en cache en session.
Tout cache tiers peut utiliser Hibernate. L'interface org.hibernate.cache.cacheprovider fournit, et il est nécessaire d'implémenter une implémentation de cache de poignée pour fournir Hibernate.
Cache de niveau de requête:
Hibernate implémente également l'intégration serrée du cache de jeu de résultats de requête et du cache de niveau 2.
Il s'agit d'une fonctionnalité facultative qui nécessite deux caches physiques supplémentaires pour enregistrer les résultats et les régions de la requête en cache lors de la dernière mise à jour d'un tableau. Ceci est tout simplement très utile pour les requêtes qui s'exécutent souvent avec les mêmes paramètres.
Cache de niveau 2:
Hibernate utilise le cache de niveau 1, par défaut, vous ne faites rien avec le cache de niveau 1. Passons directement au cache de deuxième niveau en option. Toutes les classes ne bénéficient pas de la mise en cache, il est donc important de désactiver le cache de niveau 2.
Le cache Hibernate Level 2 est défini sur deux étapes. Tout d'abord, vous devez décider quelle stratégie de concurrence utiliser. Après cela, vous pouvez configurer l'expiration du cache et utiliser le cache pour fournir des attributs de cache physiques.
Stratégie de concurrence:
Une politique de concurrence est un médiateur responsable du stockage des éléments de données dans le cache et de leur récupération du cache. Si vous souhaitez activer la mise en cache de niveau 2, vous devrez décider quelle politique de concurrence de cache utiliser pour chaque classe et collection persistantes.
Transactionnel: l'utilisation de cette stratégie pour lire principalement les données pour empêcher les transactions simultanées de données obsolètes est essentielle dans de rares cas de mises à jour.
Lecture-écriture: En utilisant à nouveau cette stratégie, la lecture principale des données est essentielle pour empêcher les transactions simultanées de données périmées dans de rares cas de mises à jour.
Non-lecture-lecture-écriture: cette stratégie ne garantit pas la cohérence entre le cache et la base de données. Avec cette stratégie, la clé n'est pas de prêter attention si les données sont rarement modifiées et que la possibilité de données périmées doit être périmée.
En lecture seule: la politique concurrencée convient aux données et ne changera jamais. Les données utilisées sont uniquement pour référence.
Si nous voulons utiliser le cache de deuxième niveau comme classe d'employés, ajoutons les éléments de cartographie requis pour indiquer à Hibernate d'utiliser une politique de cache lisible et écrite pour les instances des employés.
<? xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Hibernate-Mapping Public "- // Hibernate / Hibernate Mapping Dtd // en" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> table = "Employee"> <meta attribut = "class-description"> Cette classe contient le détail des employés. </ meta> <cache usage = "read-write" /> <id name = "id" type = "int" colonnen = "id"> <générateur /> </ id> <propriété name = "firstname" chronn = "first_name" type = "string" /> <propriété name = "lastName" chronn type = "int" /> </ class> </ hibernate-mapping>
La propriété usage = "read-write" indique à Hibernate d'utiliser un cache défini par une politique de concurrence en lecture-écriture.
Fournisseur de cache:
Après avoir envisagé la politique concurrencée de votre classe de candidats Cache, l'étape suivante consiste à sélectionner un fournisseur de cache. Hibernate Forces Sélection d'un cache pour servir l'ensemble de l'application.
Cache fourni dans le fichier de configuration Hibernate.cfg.xml spécifié. Sélectionnez Ehcache comme fournisseur de cache de deuxième niveau:
<? xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Hibernate-Configuration System "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate "> org.hibernate.dialect.mysqldialect </ propriété> <propriété name = "hibernate.connection.driver_class"> com.mysql.jdbc.driver </ propriété> <! - Supposons que les étudiants soient le nom de la base de données -> <propriété name = "Hibernate.connection.url"> jdbc: mysql: // localhost / test </prewet> <frout name = "hibernate.connection.username"> root </ propriété> <propriété name = "hibernate.connection.password"> root123 </ propriété> <propriété name = "hibernate.cache.provider_class"> org.hibernate.cache.ehcacheprovider </ propriété> <! ressource = "employee.hbm.xml" /> </ session-factory> </ hibernate-configuration>
Maintenant, vous devez spécifier les propriétés de la zone de cache. Ehcache a son propre fichier de configuration ehcache.xml, dans l'application dans ClassPath. Dans ehcache.xml, la configuration du cache de classe des employés peut ressembler à ceci:
<diskstore path = "java.io.tmpdir" /> <defaultCacheMaMELelementsInMemory = "1000" Eternal = "false" TimeToidleSonds = "120" TimetolivesEconds = "120" overflowtodisk = "true" /> <cache name = "employee" maxElementsInMemory = "500" eternal = "true" timetoidleconds = "0" timetoliveseconds = "0" overflowtodisk = "false" />
C'est tout, activez maintenant le cache secondaire de la classe des employés et Hibernate a maintenant le cache secondaire, chaque fois que vous parcourez un employé ou lorsque l'employé est chargé par un identifiant.
Vous devez analyser toutes vos classes et sélectionner la stratégie de mise en cache appropriée pour chaque classe. Parfois, le cache secondaire peut dégrader les performances de l'application. Il est donc recommandé à l'application de référence qui ne permet pas la mise en cache pour la première fois, ce qui est très adapté à la mise en cache et à la vérification des performances. Si le cache n'améliore pas les performances du système, il est dénué de signification de faire n'importe quel type de cache.
Cache de niveau de requête:
En utilisant le cache de requête, il doit être activé d'abord dans le fichier de configuration de la propriété hibernate.cache.use_query_cache = "true". Si cette propriété est définie sur true, laissez Hibernate créer le cache requis en mémoire pour enregistrer l'ensemble de requête et d'identifiant.
Ensuite, en utilisant le cache de requête, vous pouvez utiliser la méthode SetCacheable (booléenne) de la classe de requête. Par exemple:
Session Session = SessionFactory.OpenSession (); Query Query = Session.CreateeQuery ("From Employee"); Query.SetCachable (true); list Users = Query.List (); SessionFactory.CloseSESE ();Hibernate prend également en charge le support de cache très fin à travers le concept d'une zone de cache. Le cache fait partie du cache donné un nom.
Session Session = SessionFactory.OpenSession (); Query Query = Session.CreateeQuery ("From Employee"); Query.SetCachable (true); query.setCacheRegion ("Employee"); list Users = Query.List (); SessionFactory.CloseSESE ();Ce code utilise une méthode pour indiquer Hibernate pour stocker et trouver des requêtes sur les employés du cache.
Hibernate natif sql
Vous pouvez utiliser SQL natif pour exprimer des requêtes de base de données. Si vous souhaitez utiliser des fonctions spécifiques à la base de données, telles que les invites de requête ou connecter des mots clés dans Oracle. HiberNate3.x permet l'utilisation d'instructions SQL manuscrites, y compris les procédures stockées, toutes les opérations de création, de mise à jour, de suppression et de chargement.
L'application créera une requête SQL native (sur l'interface de session) à partir de la méthode de la session CreateSQLQuery ():
Public SqlQuery CreateSQLQuery (String SqlString) lève HiberNateException
Lorsque vous transmettez une requête SQL à CreateSQLQuery (), vous pouvez utiliser la méthode Addentity () associée à toute entité Hibernate existante, ou un résultat scalaire en utilisant la méthode Addentity (), AddJoin () et AddScalar ().
Requête scalaire:
La requête SQL la plus basique consiste à obtenir une liste de scalaires (valeurs numériques) à partir d'une ou plusieurs tables. Voici les valeurs de la syntaxe à l'aide de scalaires SQL natifs:
String SQL = "SELECT FIrst_name, salaire de l'employé"; SQLQuery query = session.cretesqlQuery (SQL); query.setResultTransformrer (critères.alias_to_entity_map); lister les résultats = query.list ();
Query entité:
Les requêtes ci-dessus toutes les valeurs scalaires renvoient, c'est-à-dire les données "nues" renvoyées à partir du résultat. Ce qui suit est la syntaxe pour obtenir des objets entités dans son ensemble à partir de la requête SQL native via la méthode Addentity ().
String SQL = "SELECT * FROM EMPLESYE"; SQLQuery Query = Session.cretesqlQuery (SQL); Query.AdDentity (Employee.Class); List Results = Query.List ();
Nommé SQL Query:
Ce qui suit est la syntaxe pour obtenir des objets entités à partir de requêtes SQL natives et utiliser des requêtes SQL nommées via la méthode Addentity ().
String SQL = "SELECT * FROM EMPLESYEE WHERE ID =: Employee_ID"; SQLQuery Query = Session.cretesqlQuery (SQL); Query.AdDentity (Employee.Class); Query.SetParameter ("Employee_ID", 10); List Results = Query.List (); Exemple SQL natif:
Considérez la classe POJO suivante:
Employé de classe publique {private int id; String privé FirstName; String privé LastName; Salaire int privé; Employee public () {} Public Employee (String fname, String lname, int salaire) {this.firstName = fname; this.lastName = lname; this.salary = salaire; } public int getID () {return id; } public void setid (int id) {this.id = id; } public String getFirstName () {return firstName; } public void setFirstName (String first_name) {this.firstname = first_name; } public String getLastName () {return lastName; } public void setLastName (string last_name) {this.lastname = last_name; } public int getSalary () {return salaire; } public void setsalary (int salaire) {this.salary = salaire; }}Créons la table des employés suivants pour stocker l'objet de l'employé:
Créer un employé de table (id int not null auto_increment, first_name varchar (20) par défaut null, last_name varchar (20) par défaut null, salaire int null, clé primaire (id));
Ce qui suit sera des fichiers mappés.
<? xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Hibernate-Mapping Public "- // Hibernate / Hibernate Mapping Dtd // en" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> table = "Employee"> <meta attribut = "class-description"> Cette classe contient le détail des employés. </ meta> <id name = "id" type = "int" chronn = "id"> <générateur /> </ id> <propriété name = "firstName" colonnen = "first_name" type = "string" /> <propriété name = "lastName" chronny = "last_name" type = "int" /> </ class> </ HOBERN-MUMNY = "Salary" Type = "int"
Enfin, nous créerons la méthode principale () de la classe d'application à exécuter, et nous utiliserons les applications de requête SQL natives:
import java.util. *; import org.hibernate.hibernateException; import org.hibernate.Session; import org.hibernate.transaction; import org.hibernate.essionfactory; import org.hibernate.sqlquery; import org.hibernate.criteria; import org.hibernate.hibernate; import org.hibernate.cfg.configuration; classe publique ManageEmployee {private static session factory; public static void main (String [] args) {try {factory = new Configuration (). configure (). buildSessionFactory (); } catch (Throwable ex) {System.err.println ("Échec de la création de l'objet SessionFactory." + Ex); Jetez une nouvelle exceptionIninializizerError (ex); } ManageMloyee me = new ManageMloyee (); / * Ajouter quelques enregistrements d'employés dans la base de données * / Integer empid1 = me.addemployee ("zara", "Ali", 2000); Integer Empid2 = me.addemployee ("Daisy", "Das", 5000); Integer Empid3 = me.addemployee ("John", "Paul", 5000); Integer empid4 = me.addemployee ("mohd", "yasee", 3000); / * Énumérez les employés et leur salaire à l'aide de Scalar Query * / me.ListEmployEesscalar (); / * Énumérez les informations complètes des employés à l'aide de l'entité requête * / me.ListEmployeENesTity (); } / * Méthode pour créer un employé dans la base de données * / entier public addEmployee (String fname, String lname, int salaire) {session session = factory.opencession (); Transaction tx = null; EmployeeId entier = null; try {tx = session.begintransaction (); Employé employé Employé = nouvel employé (FNAME, LNAME, SALAIRE); EmployeeId = (entier) Session.Save (employé); tx.Commit (); } catch (hibernateException e) {if (tx! = null) tx.rollback (); e.printStackTrace (); } enfin {session.close (); } return EmployeeId; }! Transaction tx = null; try {tx = session.begintransaction (); String sql = "SELECT FIRTS_NAME, SALAIRE FROM EMPLESYE"; SqlQuery query = session.cretesqlQuery (SQL); query.setResultTransformrer (critères.alias_to_entity_map); Lister data = query.list (); pour (objet objet: data) {map row = (map) objet; System.out.print ("prénom:" + row.get ("first_name")); System.out.println (", salaire:" + row.get ("salaire")); } tx.Commit (); } catch (hibernateException e) {if (tx! = null) tx.rollback (); e.printStackTrace (); } enfin {session.close (); }} / * Méthode pour lire tous les employés à l'aide de l'entité Query * / public void listEmployeeSentity () {session session = factory.opencession (); Transaction tx = null; try {tx = session.begintransaction (); String SQL = "SELECT * FROM EMPLESYE"; SqlQuery query = session.cretesqlQuery (SQL); Query.Addentity (employee.class); Lister les employés = query.list (); pour (iterator iterator = employés.iterator (); iterator.hasnext ();) {employee employé = (employé) iterator.next (); System.out.print ("prénom:" + employee.getFirstName ()); System.out.print ("nom de famille:" + employee.getLastName ()); System.out.println ("Salaire:" + employee.getsalary ()); } tx.Commit (); } catch (hibernateException e) {if (tx! = null) tx.rollback (); e.printStackTrace (); } enfin {session.close (); }}} Compiler et exécuter:
Voici les étapes pour compiler et exécuter l'application ci-dessus. Veuillez vous assurer que Path et ClassPath sont définis de manière appropriée avant de compiler et d'exécuter.
Exécutez le fichier binaire ManageMloyee pour exécuter le programme.
Les résultats suivants seront obtenus et l'enregistrement sera créé dans le tableau des employés.
$ java managemployee
...... Divers messages de journal s'affichent ici ......... Prénom: Zara, Salaire: 2000 Nom: Daisy, Salaire: 5000 Nom de la première fois: John, Salaire: 5000 Nom de MOHD, Salaire: 3000 Nom de la première: Nom de Zara: Ali Salaire: 2000 Nom de MOHD: Salaire de Yasee: 3000
Si vous vérifiez le tableau des employés, il devrait enregistrer qu'il a:
MySQL> SELECT * à partir de l'employé;
+ ---------------------------------- + ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------