1. Cartographie d'association unidirectionnelle un à plusieurs
Le modèle d'objet de la relation un-à-plusieurs est souvent observé dans la vie quotidienne. Prenez les étudiants et les cours à titre d'exemple. Il y a plusieurs élèves dans une classe, donc la relation entre la classe et les élèves est une relation un à plusieurs, cartographiée dans le modèle d'objet, comme le montre la figure ci-dessous:
Le modèle d'objet montre que cette relation un-à-plusieurs est maintenue par une extrémité, donc la cartographie dans un modèle de relation signifie qu'il y aura plusieurs étudiants dans un domaine de classe, qui forme une relation un à plusieurs. Les informations sur les élèves peuvent être obtenues par le biais de la classe. Le modèle de relation correspondant est le suivant:
1. Configuration de base
Avec le modèle d'objet, puis mappez-les en code relationnel correspondant. Lorsque vous effectuez une cartographie relationnelle, vous devez ajouter la balise <o-à-many> à une extrémité. De plus, vous devez ajouter l'attribut SET à une extrémité. Il prend en charge le chargement paresseux, puis ajoutez la balise de set dans le fichier de mappage et spécifiez une relation un à plusieurs, afin que vous puissiez interroger et obtenir l'extrémité multiple à une extrémité.
Classes et mappages de fichiers:
C'est la fin la plus importante du modèle. À cette extrémité, vous devez ajouter l'attribut SET correspondant et ajouter la balise SET dans le fichier de configuration. Vous pouvez configurer l'objet <One-to-Many> correspondant dans la balise SET. Le code d'objet Classes.Java spécifique est le suivant:
package com.src.hibernate; import java.util.set; Classes publiques Classes {private int id; public int getID () {return id; } public void setid (int id) {this.id = id; } public String getName () {Nom de retour; } public void setName (string name) {this.name = name; } nom de chaîne privée; // Set prend en charge le chargement paresseux des étudiants en jeu privé; Set public getStudents () {return étudiants; } public void SetStudants (Set Students) {this.STUDENTS = étudiants; }}L'attribut SET est utilisé dans l'objet Classes, mais il explique uniquement les attributs de chargement retardés et ne configure pas l'objet correspondant pour l'attribut. L'objet de l'attribut doit être configuré dans le fichier de mappage. Vous devez ajouter une balise SET et ajouter la balise <o-à-many> à la balise de set. Le code spécifique est le suivant:
<? xml version = "1.0"?> <! Doctype Hibernate-Mapping public "- // Hibernate / Hibernate Mapping Dtd 3.0 // en" "http://hibernate.sourceforge table = "t_classes"> <id name = "id"> <generator // id> <propriété name = "name" /> <set name = "étudiants"> <key column = "Classid"> </ key> </ hibernate-mapping> </ne-to-many> </ set> </ class> </ hibernate-mapping>
Le code et les fichiers de mappage dans l'objet étudiant correspondant ne nécessitent aucune configuration spéciale, ils n'ont qu'à être écrit en fonction de la méthode d'écriture habituelle. La méthode de configuration spécifique ne sera pas décrite en détail, elle est très simple. Après la configuration, vous devez générer l'instruction SQL correspondante. Lors de la conversion du modèle d'objet en un modèle relationnel, Hibernate génère l'instruction correspondante comme suit:
Alter Table T_Student Drop Foreign Key FK4B9075705E0AFEFE Table Drop Table If existe T_CLASSES DROP TABLE IF existe t_student Créer une table T_CLASSES (ID INTEGER NON NULL AUTO_INCRAMENT, NAM Clé primaire (ID)) Alter Table T_Student Ajouter un index FK4B9075705E0AFEFE (CASSIDID), Ajouter une contrainte FK4B9075705E0AFEFE Foreign Key (ClassesID) références T_Class (ID)
Le modèle de relation correspondant généré est illustré ci-dessous:
En comparant les instructions SQL et les modèles de relations, l'association entre les tables correspondantes est maintenue par des clés étrangères. Tout d'abord, créez deux tables, spécifiez la clé principale de la table et enfin ajoutez une relation d'association de clé étrangère un-à-plusieurs.
2. Opérations de base
Les opérations de la base de données ne sont rien de plus que lire et écrire, et la modification est également un type d'écriture. Ensuite, voyons comment écrire et lire les opérations dans la base de données.
(1) Écrire des données:
Lorsque vous rédigez des données, vous devez faire attention à la relation un-à-plusieurs, vous devez donc ajouter plusieurs classes étudiantes lorsque vous les ajoutez. De plus, comme l'attribut SET correspondant est ajouté aux classes, vous devez utiliser HashSet à ajouter lors de l'ajout d'objets étudiants, afin que vous puissiez réaliser une relation un à plusieurs. Le code spécifique est le suivant:
public void testsave2 () {session session = null; essayez {session = hibernateutils.getSession (); session.begintransaction (); Student Student1 = New Student (); Student1.setName ("Zhangsan"); Session.Save (Student1); Student Student2 = New Student (); Student2.SetName ("Lisi"); Session.Save (Student2); Classes Classes = Nouvelles classes (); Classes.SetName ("ClassOne"); Définir les étudiants = new HashSet (); Students.Add (Student1); Students.Add (Student2); classes.setStudents (étudiants); // Les données peuvent être enregistrées avec succès // mais une instruction de mise à jour supplémentaire sera publiée pour maintenir la relation car c'est une raison à une Session.Save (classes); session.getTransaction (). commit (); } catch (exception e) {e.printStackTrace (); session.getTransaction (). Rollback (); } enfin {hibernateUtils.closeSession (session); }} Ensuite, après que les données correspondantes générées en exécutant le cas de test ci-dessus sont écrites dans la base de données, la figure suivante est la suivante:
(2) Lire les données:
L'opération d'écriture est relativement simple. Il vous suffit d'ajouter tous les objets chargés à l'état transitoire et d'exécuter la méthode correspondante pour insérer le contenu. Cependant, l'opération de lecture correspondante sera un peu plus compliquée. Parce qu'il est nécessaire d'itérer d'obtenir tous les objets étudiants, cette relation un-à-plusieurs n'est pas très efficace. Le code spécifique est le suivant:
package com.test.hibernate; Importer java.util.iterator; import java.util.set; import com.src.hibernate. *; Importer Junit.Framework.TestCase; import org.hibernate.Session; La classe publique One2ManyTest étend TestCase {public void testload1 () {session session = null; essayez {session = hibernateutils.getSession (); session.begintransaction (); // Obtenez des informations de classe avec la clé primaire 5 classes Classes = (classes) session.load (classes.class, 5); // Imprimer le System d'information de la classe.out.println ("classes.name =" + classes.getName ()); // Définit l'ensemble des élèves et chargez l'ensemble de l'élève via l'ensemble de classes Students = Classes.GetStudents (); // itérera l'ensemble et imprimez les informations de l'étudiant dans l'ensemble pour (iterator iter = étudiants.iterator (); iter.hasnext ();) {étudiant étudiant = (étudiant) iter.next (); System.out.println ("Student.Name =" + Student.getName ()); } session.getTransaction (). commit (); } catch (exception e) {e.printStackTrace (); session.getTransaction (). Rollback (); } enfin {hibernateUtils.closeSession (session); }}}Les instructions et informations générées correspondantes sont les suivantes:
HiberNate: sélectionnez Classes0_.id en tant qu'ID1_0_, classes0_.name comme name1_0_ de T_Classes Classes0_ Where Classes0_.id =? Classes.Name = ClassOne Hibernate: SELECT Students0_.ClasSesId As Classid1_, Students0_.id As ID1_, Students0_.id As ID0_0_, Students0_.name As Name0_0_ From T_Student Students0_ Where Students0_.ClasseSid =? Student.name = Lisi Student.name = Zhangsan
2. Cartographie d'association bidirectionnelle un-à-plusieurs
Ici, nous continuons à utiliser les étudiants et les cours comme exemples. Il existe une relation un-à-plusieurs entre la classe et les élèves. Il y a plusieurs étudiants dans une classe. Contrairement à l'article précédent, la relation ici est à double sens, c'est-à-dire une fin et une extrémité maintiennent la relation en même temps, donc son diagramme d'objet est le suivant:
Le diagramme du modèle de relation correspondant ne change pas beaucoup, car la relation entre eux est bidirectionnelle, donc les deux extrémités du modèle de relation maintiennent la relation relationnelle en même temps et la mappent au modèle de relation comme indiqué dans la figure ci-dessous:
Dans une association unidirectionnelle un à plusieurs, le fichier de mappage ne doit être spécialement configuré à une extrémité. Utilisez la configuration <o-à-many> et utilisez le SET ITERATOR dans le modèle d'objet pour définir le modèle d'objet OUSELLED. Cependant, la différence est que dans une association bidirectionnelle, l'association de clé étrangère correspondante à l'autre extrémité doit être ajoutée à l'extrémité multiple. À l'heure actuelle, la relation de <plusieurs à un> doit être utilisée à l'extrémité multiple pour indiquer cette bidirectionnalité.
1. Cartographie
Les cours et les étudiants sont également utilisés comme exemples ici. Le contenu de l'extrémité des classes est le même que ci-dessus et ne changera pas, mais la configuration des étudiants aux extrémités multiples changera, c'est-à-dire que la balise <plusieurs à un> doit être ajoutée au fichier de mappage.
La configuration du fichier de mappage student.hbm.xml nécessite l'ajout d'une balise de colonne de clé étrangère <plusieurs à un>, et le nom de la colonne doit être cohérent avec le nom de la colonne de clé étrangère de Classes.hbm.xml. Le code spécifique est le suivant:
<? xml version = "1.0"?> <! Doctype Hibernate-Mapping public "- // Hibernate / Hibernate Mapping Dtd 3.0 // en" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <Hernate-Mapping> <classe nom = "com.src.hibern table = "t_student"> <id name = "id"> <générateur / générateur /> </ id> <propriété name = "name" /> <! - Ajoutez une nouvelle colonne de classes dans l'étudiant d'un côté, et le nom de la colonne devrait être le même que la liste de classes.hbm.xml -> <plusieurs à un nom = "classes" colonnes = "CASSID"> </fr
La configuration du fichier de mappage de classes.hbm.xml est la même que dans l'article précédent. Il convient de noter que le mappage d'attribut SET est ajouté au fichier Classes.java et correspond à l'objet étudiant. Par conséquent, la balise SET doit être ajoutée au fichier de mappage pour indiquer que l'itérateur SET est utilisé dans le modèle d'objet. La configuration spécifique est la suivante:
<? 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> <classe nom = "com.src.hiber.Hibern. table = "t_classes"> <id name = "id"> <generator // id> <propriété name = "name" /> <set name = "étudiants" inverse = "true"> <key column = "Classid"> </ key> </ hurnate mapping> </ one-to-many> </ set> </ class> </ hibernate-mapping>
2. Classe
La configuration du fichier de mappage correspond directement à la classe, donc avec le fichier de mappage, vous pouvez écrire la classe correspondante. Avec la même classe, vous pouvez savoir comment écrire le fichier de mappage correspondant. Jetons un œil à la façon d'écrire le code de classe correspondant.
La classe Student.java nécessite l'ajout d'attributs d'objets de classe associés à la classe, et vous pouvez obtenir des informations liées aux classes lors du chargement de l'élève.
package com.src.hibernate; classe publique Student {// Classes de classe associée Classes privées; Classes publiques getClasses () {Classes de retour; } public void setClasses (classes classes) {this.classes = classes; } // Étudiant id privé int id; public int getID () {return id; } public void setid (int id) {this.id = id; } // nom d'étudiant nom de chaîne privée; public String getName () {Nom de retour; } public void setName (string name) {this.name = name; }} Le contenu de code spécifique du fichier Classes.java est affiché dans l'article précédent et ne sera pas décrit en détail ici.
Avec le modèle d'objet, le modèle de relation est généré. L'instruction SQL générée est la suivante:
Alter Table T_Student Drop Foreign Key FK4B907570FC588BF4 DROP TABLE IF existe T_CLASSES TABLE DE DROIT IF EST T_STUDENT CREATE TABLE T_CLASSES (ID INTEGER NON NULL AUTO_INCRAMENT clé entière, clé primaire (id)) alter le tableau t_student Ajouter un index fk4b907570fc588bf4 (ClassesID), Ajouter une contrainte FK4B907570FC588BF4 Foreign Key (ClassID) références t_classes (ID)
3. Fonctionnement des données
Après avoir établi une structure de table, j'ai écrit une méthode de test pour vérifier le fonctionnement des données. Tout d'abord, jetons un coup d'œil à l'insertion des données et insérez les données dans la structure du tableau. Il y a deux situations lors de la rédaction de données. L'une consiste à créer d'abord un objet de classes, à écrire l'objet dans la base de données, puis à créer un objet étudiant et à ajouter l'objet étudiant à l'objet Classes; L'autre consiste à créer d'abord un objet étudiant, à écrire l'objet étudiant à la base de données, puis à créer un objet de classes pour ajouter l'objet étudiant à l'objet Classes. Ces deux types d'opérations sont différents en fin de compte, alors comparons.
3.1 Écrivez d'abord la classe, puis écrivez les élèves
Après avoir d'abord écrit la classe dans la base de données, l'objet Classes entre dans l'état transitoire et a une ligne dans la base de données. Ensuite, écrivez l'objet étudiant. L'objet étudiant recherchera la clé primaire des classes correspondantes et l'écrira dans le tableau. Par conséquent, les données du modèle de relation sont non vides et le code enregistré est le suivant:
public void testsave () {session session = null; essayez {// créer une session de session Session = hibernateUtils.getSession (); // Open Transaction Session.beginTransaction (); // Créer un objet de classe et un objet de classe d'écriture dans les classes de base de données Classes = new Classes (); classes.setName ("classe"); session.save (classes); // Créer un objet étudiant 1 et écrivez un objet étudiant à la base de données Student Student1 = new Student (); Student1.setName ("Zhangsan"); Student1.setClasses (classes); Session.Save (Student1); // Créer un objet Student 2 et écrire l'objet étudiant dans la base de données Student Student2 = new Student (); Student2.SetName ("Lisi"); Student2.SetClasses (classes); Session.Save (Student2); session.getTransaction (). commit (); } catch (exception e) {e.printStackTrace (); session.getTransaction (). Rollback (); } enfin {hibernateUtils.closeSession (session); }} La liste d'informations correspondante dans la base de données d'écriture est la suivante:
3.2 Écrivez d'abord les élèves, puis la classe
Écrivez d'abord les élèves dans la base de données. À l'heure actuelle, parce que le tableau étudiant doit obtenir les informations principales de la colonne de classe correspondante, mais parce que les informations de classe sont converties à l'état transitoire, il y aura une valeur nulle lors de la rédaction des informations de l'élève. Le code est le suivant:
La vue de base de données correspondante après l'écriture est la suivante:
En comparant les deux opérations d'écriture, différents résultats apparaissent parce que l'ordre des deux écritures est différent, mais parce qu'il s'agit d'une association bidirectionnelle, aucune exception ne se produit pendant l'écriture.
4. Opération de lecture
Par rapport à la rédaction de données, la lecture des données devient très simple. Parce qu'il s'agit d'une association bidirectionnelle, la lecture des données est également bidirectionnelle. Les informations de l'autre extrémité peuvent être lues à partir de n'importe quelle extrémité, comme indiqué dans le code suivant:
public void testload1 () {session session = null; essayez {session = hibernateutils.getSession (); session.begintransaction (); // Lire les informations de l'étudiant via des classes de classe Classes = (classes) Session.Load (classes.class, 1); System.out.println ("classes.name =" + classes.getName ()); Définir les étudiants = classes.getSudents (); for (iterator iter = students.iterator (); iter.hasnext ();) {étudiant étudiant = (étudiant) iter.next (); System.out.println ("Student.Name =" + Student.getName ()); } // lire les informations de classe via l'élève étudiant Stu = new Student (); Stu = (Student) Session.load (Student.class, 1); System.out.println ("Informations de classe de charge via Student Classes.id =" + stu.getClasses (). GetId ()); session.getTransaction (). commit (); } catch (exception e) {e.printStackTrace (); session.getTransaction (). Rollback (); } enfin {hibernateUtils.closeSession (session); }}Exécutez l'instruction de test ci-dessus et les informations d'instruction correspondantes générées sont les suivantes:
HiberNate: sélectionnez Classes0_.id en tant qu'ID1_0_, classes0_.name comme name1_0_ de T_Classes Classes0_ Where Classes0_.id =? Classes.Name = Class Hibernate: Sélectionnez Students0_.ClassesId As Classid1_, Students0_.id as id1_, Students0_.id as id0_0_, Students0_.name as name0_0_, students0_.classesid as Classid0_0_ de T_Student Students0_ Where Students0_.classesid =? Student.name = Lisi Student.name = Zhangsan
Chargement des informations de classe par les classes des élèves.id = 1