La principale recherche de cet article est le contenu pertinent de la requête HQL Hibernate, comme suit.
Hibernate Query Language (HQL) est une instruction de requête complètement orientée objet avec des fonctions de requête très puissantes; Il a le polymorphisme, l'association et d'autres caractéristiques. HQL Query est également la méthode de requête officiellement recommandée par Hibernate.
Ensuite, nous analysons les méthodes de requête pertinentes grâce à une étude de cas
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.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.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>
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>
/ * Renvoie la liste des attributs du jeu de résultats, le type d'élément et les types d'attribut dans la classe d'entité sont les mêmes * / list <string> students = session.createeQuery ("SELECT NAME FROM Student"). List (); / * Travel * / for (iterator <string> iter = Students.iterator (); iter.hasnext ();) {String name = (string) iter.next (); System.out.println (nom); }Remarque: Lors de l'interrogation d'un seul attribut, l'ensemble retourné est une collection et le type de l'élément de collection est le type d'attribut.
/ * Interroger plusieurs propriétés, renvoyer un tableau d'objets * / list <objet []> students = session.createeQuery ("SELECT ID, nom dans l'étudiant"). List (); / * Transip * / for (iterator <object []> iter = étudiants.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Remarque: La question des attributs multiples renvoie une collection de tableaux d'objets de type. C'est facile à comprendre. Lorsque vous interrogez un seul attribut est le type d'élément de collection renvoyé, c'est le type d'attribut, mais qu'en est-il de plusieurs types? Cela doit être un tableau d'objets à traiter, c'est-à-dire objet [].
/ * Nous définissons le constructeur correspondant pour l'objet Entity, puis nous pouvons retourner une collection de types d'objets d'entité en interrogeant l'objet * / liste Students = Session.CreateeQuery ("Select New Student (id, nom) From Student"). List (); / * Travel * / for (iterator iter = Students.iterator (); iter.hasnext ();) {étudiant étudiant = (étudiant) iter.next (); System.out.println (Student.getId () + "," + Student.getName ()); }Remarque: En plus de la deuxième méthode, nous renvoyons un tableau d'objets, nous pouvons également définir le constructeur correspondant pour l'objet Entity, puis interroger l'objet en interrogeant l'objet, puis renvoyer une collection de types d'entités.
/ * Les alias peuvent être utilisés * / list <objet []> Students = Session.CreateeQuey ("SELECT S.ID, S.NAME FROM Student S"). List (); / * Transip * / for (iterator <object []> iter = étudiants.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); } / * Return est une collection de types d'objets d'entité * / list <Student> Students = Session.CreateeQuy ("From Student"). List (); / * Transparep * / for (iterator <Student> iter = Students.iterator (); iter.hasnext ();) {Student Student = (Student) iter.next (); System.out.println (Student.GetName ()); }Remarque: Les entités de requête peuvent utiliser directement la forme du nom de la classe.
/ * Utilisez SELECT pour utiliser Alias * / List <Student> Students = Session.CreateeQuey ("SELECT S FROM Student S"). List (); / * Transparep * / for (iterator <Student> iter = Students.iterator (); iter.hasnext ();) {Student Student = (Student) iter.next (); System.out.println (Student.GetName ()); }Remarque: Si vous souhaitez utiliser le mot clé SELECT, vous devez utiliser un alias. Un autre point doit être noté: HQL ne prend pas en charge la forme de sélection *.
/ ** * Si vous utilisez la liste pour interroger l'objet d'entité, une instruction de requête sera publiée pour obtenir les données de l'objet d'entité * * HiberNate: SELECT Student0_.id as id0_, student0_.name as name0_, * étudiant0_.createtime as Createtime0_ Étudiant "). List (); / * Travel * / for (iterator <Student> iter = Students.iterator (); iter.hasnext ();) {étudiant étudiant = (étudiant) iter.next (); System.out.println (Student.GetName ()); }Remarque: Lors de l'utilisation de la méthode .list () pour interroger les objets, une seule instruction sera publiée, c'est-à-dire une instruction qui obtient les données d'objet physique.
/ ** * Le problème N + 1 se produira. Le soi-disant N + 1 fait référence à l'émission de n + 1 instructions SQL * * 1: publication d'une instruction qui interroge la liste d'identification * Hibernate: Sélectionnez Student0_.id comme col_0_0_ à partir de T_Student Student0_ * N: Sélectionner N SQL Instructions basées sur l'identifiant pour charger l'objet pertinent * Hibernate: Sélectionnez Student0_.Id As ID0_0_, étudiant 0 * Student0_.CreateTime as CreateTime0_0_, Student0_.classesId as CLASSISID0_0_ * de T_Student Student0_ Where Student0_.id =? * 11 / * Voyage * / while (iter.hasnext ()) {étudiant étudiant = (étudiant) iter.next (); System.out.println (Student.GetName ()); }Remarque: Lors de l'exécution de la requête d'objet via iterator (), des instructions N + 1 seront publiées. Tout d'abord, une déclaration sera publiée pour interroger l'ID de l'objet entité, puis des instructions N seront publiées en fonction de leurs ID respectifs pour interroger n objets. La performance formelle est relativement médiocre.
/ * Stockage de la collection interrogée dans le cache de premier niveau, c'est-à-dire le cache au niveau de la session * / list <Student> Students = Session.CreateEquery ("From Student"). List (); / * Transparep * / for (iterator <Student> iter = Students.iterator (); iter.hasnext ();) {Student Student = (Student) iter.next (); System.out.println (Student.GetName ()); } System.out.println("-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Avoid N+1 problem* * Because after performing L'opération de liste, les données seront placées dans le cache de session (cache de premier niveau), lors de l'utilisation de la publication de la liste des instructions, puis les données correspondantes seront chargées dans le cache en fonction de l'ID. Cache, il peut améliorer les performances, sinon le problème N + 1 se produira * * / Iterator <Student> iter = Session.CreateEquery (From Student "). Iterate ();Remarque: En fait, HiberNate fournit une requête Iterator () pour améliorer les performances, alors pourquoi cela aide-t-il trop? La raison en est que Iterator () récupère les données du cache de premier niveau. S'il y a des données dans le cache, son efficacité sera sans aucun doute assez puissante. Cependant, lorsque je demande la première fois, comment pourrait-il y avoir des données dans le cache? Cela conduit au soi-disant problème N + 1. Le code ci-dessus peut éviter le problème N + 1. Son idée est d'utiliser la liste () d'abord pour interroger, car après la liste () est interrogée, les données existent dans le résumé du cache de premier niveau, et lors de l'utilisation d'Iterator (), l'efficacité sera très élevée.
/ * Requête en fonction des conditions (les alias sont généralement utilisés ici, ce qui est plus pratique) * / list <object []> Students = Session.CreateeQuery ("SELECT S.ID, S.Name From Student s Where S.Name Like '% 0%'"). List (); / * Travel * / for (iterator <object []> iter = Students.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Remarque: La requête conditionnelle est la même que SQL native, qui sont toutes deux l'endroit où les mots clés. De plus, il est généralement plus pratique d'utiliser un alias. Le programme ci-dessus consiste à interroger plusieurs attributs, il renvoie donc une collection de types de tableau d'objets, et les éléments du tableau d'objets sont les attributs correspondants.
/ * Programmation Chenged * / list <objet []> Students = Session.CreateeQuery ("SELECT S.ID, S.Name From Student S Where S.Name Like?") .SetParameter (0, "% 0%") .List (); / * Travel * / for (iterator <object []> iter = Students.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Remarque: les paramètres peuvent être transmis par des espaces réservés, ce qui peut empêcher l'injection de SQL.
/ * PROGRAMMATION DE CHIP * / LIST <objet []> Students = Session.CreateeQuery ("SELECT S.ID, S.Name From Student s Where S.Name Like: MyName") .setParameter ("MyName", "% 0%") .List (); / * Array d'objet * / for (iterator <object []> iter = étudiants.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Remarque: comme: il n'y a pas d'espace après le Colon MyName, sinon une erreur se produira.
[Java] Voir la copie simple / * adopte la méthode in, un seul paramètre formel peut être utilisé * / list <objet []> étudiants = session.CreateEquery ("SELECT S.ID, S.NAME FROM Student s Where S.Id in (: ids)") .setParameterList ("ids", nouvel objet [] {1, 2, 3, 4, 5}) .List (); / * Transip * / for (iterator <object []> iter = étudiants.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Remarque: il n'y a qu'un seul paramètre formel dans les supports après IN. Lorsque nous définissons la valeur du paramètre, nous pouvons passer la valeur via le tableau d'objets.
/ * Interroger les étudiants en 2009-08, vous pouvez appeler la fonction de formatage de date de mysql * / list <object []> étudiants = session.Createequery ("SELECT S.ID, S.Name From Student s Where Date_format (S.CreateTime, '% y-% m') =?") .Setparamètre (0, "2009-08") .list (); / * Travel * / for (iterator <object []> iter = Students.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); } SimpledateFormat sdf = new SimpledateFormat ("yyyy-mm-dd hh: mm: ss"); / * Les étudiants de 2009-08-01 à 2009-08-20 peuvent appeler la fonction de formatage de date de mysql * / list <object []> Students = Session.Createequery ("Select S.Id, S.Name From Student s Where S.CreateTime Between? Et?") .SetParamètre (0, Sdf.Parse ("2009-08-01 00:00:00") .Setparamter (1, 1, 08-01 00:00:00 "). sdf.parse ("2009-08-20 23:59:59") .List (); / * Transip * / for (iterator <object []> iter = étudiants.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); } / * Utiliser SELECT * Vous devez utiliser les instructions SQL originales, et elle est similaire à HQL interroge plusieurs propriétés, il renvoie donc une collection de types de tableau d'objets * / list <objet []> étudiants = session.CreateSQLQuery ("SELECT * FROM T_STUDENT"). List (); / * Transip * / for (iterator <object []> iter = étudiants.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Remarque: HQL ne prend pas en charge le formulaire de requête de Select *, mais Hibernate prend en charge les instructions SQL originales. Nous pouvons utiliser des instructions SQL pour interroger. De plus, il est similaire aux attributs multiples de requête de HQL, il renvoie donc une collection de types de tableaux d'objets.
/ * Requête de page, setFirStResult (1) signifie commencer à partir des premières données; setMaxResult (2) signifie que 2 éléments de données sont affichés par page * / liste étudiants = session.createery ("From Student") .setFirStResult (1) .setMaxResults (2) .List (); / * Travel * / for (iterator iter = Students.iterator (); iter.hasnext ();) {étudiant étudiant = (étudiant) iter.next (); System.out.println (Student.GetName ()); } / * Query de navigation, s.classes.name naviguez de l'élève à la classe en classe (cela navigue de plus de fin à moins de fin, ce qui est également possible) * / list <Student> Students = Session.CreateeQuery ("From Student s où s.classes.name comme '% 2%'") .List (); / * Travel * / for (iterator <Student> iter = Students.iterator (); iter.hasnext ();) {étudiant étudiant = (étudiant) iter.next (); System.out.println (Student.GetName ()); }Remarque: Le nom de S.classes.Name dans l'instruction de requête ci-dessus est d'obtenir le nom de la classe de la navigation étudiante aux classes de classe. Vous pouvez également naviguer à l'envers: naviguer de la classe à l'élève pour obtenir un certain attribut. De plus, la déclaration de requête dans le programme signifie interroger tous les élèves avec 2 dans le nom de la classe.
/ * Connexion intérieure, utilisez simplement le mot-clé join * / list <object []> students = session.createequery ("select c.name, s.Name from Student s join s.classes c") .list (); / * Transaction * / for (iterator <object []> iter = Students.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Remarque: Le mot-clé de la connexion intérieure est jointe, et la connexion est toujours effectuée à l'aide d'alias et de navigation. La déclaration de requête ci-dessus signifie: Interroger le nom de classe et le nom de l'élève de la table des élèves et de la table de classe (la connexion intérieure signifie qu'il doit y avoir des attributs dignes dans l'interrogation, comme aucune classe ou aucun élève ou élèves ne peut pas interroger sans classes).
/ * Left join utilise le mot-clé gauche join * / list <object []> Students = Session.CreateeQuery ("SELECT C.NAME, S.NAME FROM Student S Left Join S.Classes C") .List (); / * Transip * / for (iterator <object []> iter = étudiants.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Remarque: le mot-clé utilisé pour la jointure de gauche est la jointure de gauche. La déclaration de requête ci-dessus signifie: à partir de la table des élèves et des classes, interrogez le nom de la classe et le nom de l'élève. Parce qu'il s'agit d'une connexion à gauche, les élèves sans cours seront également interrogés.
[Java] Afficher la copie simple / * Le mot clé de jointure est droit join * / list <object []> Students = session.CreateeQuery ("SELECT C.NAME, S.NAME FROM Student S Right Join S.Classes C") .List (); / * Transip * / for (iterator <object []> iter = étudiants.iterator (); iter.hasnext ();) {objet [] obj = (objet []) iter.next (); System.out.println (obj [0] + "," + obj [1]); }Remarque: le mot clé utilisant la jointure de droite est la jointure droite. La déclaration de requête ci-dessus signifie: à partir de la table des élèves et des classes, interrogez le nom de la classe et le nom de l'élève. Parce qu'il s'agit d'une connexion droite, les cours sans étudiants seront interrogés.
Long Count = (Long) Session.CreateeQuery ("Select Count (*) From Student"). UniQueResult ();Remarque: seules les requêtes statistiques peuvent être utilisées dans HQL avec *. UniQueResult () signifie qu'il n'y a qu'un seul ensemble de résultats et le type retourné long.
/ * Instruction de requête * / string hql = "select c.name, count (s) From Classes C JOIN C.STUDENTS S Groupe par C.Name Order by C.Name"; List <object []> Students = Session.CreateeQuery (HQL) .List (); / * Voyager * / for (int i = 0; i <étudiants.size (); i ++) {objet [] obj = (objet []) Students.get (i); System.out.println (obj [0] + "," + obj [1]); }Remarque: HQL prend également en charge le groupement, le tri, etc.
Ce qui précède est tout au sujet de l'exemple de code de requête HQL Hibernate dans cet article, 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!