One-to-many One-way and Bidirectional association mappings in the Java Hibernate framework _java

Source: Internet
Author: User
Tags generator rollback

One or one pairs of multiple one-way association mappings

The object model of a one-to-many relationship is often seen in daily life, taking students and classes, a class has a number of students, so the relationship between the class and students is a one-to-many relationship, mapping to the object model, the following figure:

The object model illustrates that this one-to-many relationship is maintained by one end, then the mapping into a relational model is a class field there will be more than one student, thus forming a one-to-many relationship, through the class can query access to student information, the corresponding relationship model as follows:

1. Basic Configuration

With the object model, let them map to the corresponding relational code, you need to add <one-to-many> tags to one end of the relationship mapping, and add the set attribute at one end, which supports deferred loading and then adds a set label to the mapping file. and indicates a one-to-many relationship so that you can get more than one end of the query.

Classes Class and Mapping file:
It is the most important end of the model, where you need to add the corresponding set properties, add the set label to the configuration file, and configure the corresponding <one-to-many> object in the set label, with the Classes.java object code as follows:

Package com.src.hibernate; 
 
Import Java.util.Set; 
 
public class Classes { 
  private int id; 
  public int getId () {return 
    ID; 
  } 
  public void setId (int id) { 
    this.id = ID; 
  } 
  Public String GetName () {return 
    name; 
  } 
  public void SetName (String name) { 
    this.name = name; 
  } 
  private String name; 
   
  Set supports deferred loading 
  private Set students; 
  Public Set getstudents () {return 
    students; 
  } 
  public void Setstudents (Set students) { 
    this.students = students; 
  } 
} 

The Set property is used in the classes object, but it only describes the deferred load property and does not have the corresponding object configured for the property, the object of the property is to be configured in the mapping file, the set label needs to be added, and the <one-to-many> tag is added to the set label. The following code is specified:

<?xml version= "1.0"?> 
<! DOCTYPE hibernate-mapping public  
  "-//hibernate/hibernate mapping DTD 3.0//en" 
  "http:// Hibernate.sourceforge.net/hibernate-mapping-3.0.dtd "> 
 
 

The corresponding student object code and mapping file does not need any special configuration, only need to write according to the usual writing can, the specific configuration method no longer detailed, very simple. Once configured, the corresponding SQL statement needs to be generated, and when the object model is transformed into a relational model hibernate the corresponding statement is generated as follows:

ALTER TABLE t_student drop FOREIGN key fk4b9075705e0afefe 
drop table if exists t_classes 
drop table if exists T_st Udent 
CREATE TABLE t_classes (ID integer NOT NULL auto_increment, name varchar (255), primary key (ID)) 
create Tabl e t_student (ID integer NOT NULL auto_increment, name varchar (255), Classesid Integer, primary key (ID)) 
ALTER TABLE t _student Add index Fk4b9075705e0afefe (CLASSESID), add constraint Fk4b9075705e0afefe foreign key (CLASSESID) references T_ Classes (ID) 

The corresponding relational model generated is the following diagram:

In contrast to SQL statements and relational models, the correlation between the corresponding tables is maintained through a foreign key, first creating two tables, specifying the primary key of the table, and finally adding a one-to-many foreign key association.

2. Basic operation
in the operation of the database is nothing but read and write two, modify also belong to write one, and then see how to write to the database and read operations.

(1) Write Data:
writing data requires attention to a one-to-many relationship, so you need to add multiple student classes when you add them, and because you add the corresponding set attribute in classes, you should add the student object by using HashSet to add it, so that you can achieve a one-to-many relationship. The following code is specified:

public void TestSave2 () {session 
  Session=null; 
  try{ 
    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=new Classes (); 
    Classes.setname ("Classone"); 
     
    Set students=new hashset (); 
    Students.add (student1); 
    Students.add (Student2); 
     
    Classes.setstudents (students); 
    Data can be saved successfully 
    //But redundant UPDATE statements will be issued to maintain the relationship because it is a one-to-many cause 
    session.save (classes); 
    Session.gettransaction (). commit (); 
  catch (Exception e) { 
    e.printstacktrace (); 
    Session.gettransaction (). rollback (); 
  } finally{ 
    Hibernateutils.closesession (session); 
  } 
 

The corresponding data generated by running the test case above is written to the database in the following figure:

(2) reading data:
write operation is relatively simple, just want to add all loaded objects to the transient state, run the appropriate method can insert content, but the corresponding read operation is slightly more complex, Because of the need to iterate over all the student objects, this one-to-many relationship is not as efficient as the following code:

Package com.test.hibernate; 
Import Java.util.Iterator; 
Import Java.util.Set; 
Import com.src.hibernate.*; 
Import Junit.framework.TestCase; 
 
Import org.hibernate.Session; 
    public class One2manytest extends TestCase {public void TestLoad1 () {session session=null; 
      try{session=hibernateutils.getsession (); 
       
      Session.begintransaction (); 
      Gets the class information for the primary key of 5 Classes classes= (Classes) session.load (classes.class,5); 
      Print class information System.out.println ("Classes.name=" +classes.getname ()); 
      Set up the student collection, load the Student collection set Students=classes.getstudents () through the class; Iteration collection, print collection of information for the middle school students for (iterator Iter=students.iterator (); Iter.hasnext ();) {Student student= (Student) iter.ne 
         
        XT (); 
      System.out.println ("Student.name=" +student.getname ()); 
    Session.gettransaction (). commit (); 
      }catch (Exception e) {e.printstacktrace (); 
    Session.gettransaction (). rollback (); }finally{HibeRnateutils.closesession (session); 

 } 
  } 
}

The corresponding statements and information generated are as follows:

Hibernate:select classes0_.id as id1_0_, classes0_.name as name1_0_ from t_classes where classes0_? 
Classes.name=classone 
hibernate:select Students0_.classesid as classesid1_, 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 

Two or one pairs of multiple bidirectional association mappings
Here we continue to use students and classes as examples, class and students are a one-to-many relationship, a class with more than one student, and the previous article is different from the relationship here is two-way, that is, one end and many at the same time maintain the relationship, so its object map as follows:

The corresponding relational model diagram does not change much because the relationship between them is bidirectional, so the relationship is maintained at both ends of the relational model, mapped to the relational model as shown in the following illustration:

Mapping a file in a One-to-many one-way association requires a special configuration on one end, using the <one-to-many> configuration, and using the set iterator in the object model to set the external object model. But the difference is that in a two-way relationship you need to add the corresponding other end of the foreign Key Association at one end, at which point you have to use the <many-to-one> Association to indicate this two-way.

1, mapping

Here also uses classes and student to do the example, at the classes end of the same content and the same does not occur, but more than one end of the student configuration will change, that is, in the mapping file need to add <many-to-one> tags.
The Student.hbm.xml mapping file configuration requires the addition of a foreign key column <many-to-one> label, and the name of the column is consistent with the name of the foreign key column of Classes.hbm.xml, as follows:

<?xml version= "1.0"?> 
<! DOCTYPE hibernate-mapping public  
  "-//hibernate/hibernate mapping DTD 3.0//en" 
  "http:// Hibernate.sourceforge.net/hibernate-mapping-3.0.dtd "> 
 
 

The configuration of the Classes.hbm.xml mapping file is the same as in the previous article, and it should be noted that the set property mappings added to the Classes.java file correspond to the student object, so you need to add a set tag in the mapping file to indicate that the set iterator is used in the object model, configuring the following code:

<?xml version= "1.0"?> 
<! DOCTYPE hibernate-mapping public  
  "-//hibernate/hibernate mapping DTD 3.0//en" 
  "http:// Hibernate.sourceforge.net/hibernate-mapping-3.0.dtd "> 
 
 

2, class

Mapping file configuration is directly corresponding to the class, so with the mapping file can write the corresponding class, the same class can know how the corresponding mapping file to write, then to see how the corresponding class code to write.
Student.java class, you need to add an associated class object attribute to the class, and you can get classes information when loading the Student.

Package com.src.hibernate; 
 
public class Student { 
   
  //Associated class object 
  private Classes Classes; 
  Public Classes getclasses () {return 
    Classes; 
  } 
  public void setclasses (Classes Classes) { 
    this.classes = Classes; 
  } 
   
  Student ID 
  private int id; 
  public int getId () {return 
    ID; 
  } 
  public void setId (int id) { 
    this.id = ID; 
  } 
   
  Student name 
  private String name; 
  Public String GetName () {return 
    name; 
  } 
  public void SetName (String name) { 
    this.name = name; 
  } 
   
} 

Classes.java file specific code content see the article, here is not detailed.
With the object model, the relational model is generated and the resulting SQL statement is as follows:

ALTER TABLE t_student drop FOREIGN key fk4b907570fc588bf4 
drop table if exists t_classes 
drop table if exists T_st Udent 
CREATE TABLE t_classes (ID integer NOT NULL auto_increment, name varchar (255), primary key (ID)) 
create Tabl e t_student (ID integer NOT NULL auto_increment, name varchar (255), Classesid Integer, primary key (ID)) 
ALTER TABLE t _student Add index Fk4b907570fc588bf4 (CLASSESID), add constraint Fk4b907570fc588bf4 foreign key (CLASSESID) references T_ Classes (ID) 

3. Data operation

Set up a table structure and then write a test method to verify the operation of the data, first look at the insertion of data, insert data into the table structure, there are two situations when writing data, one is to create a classes object first, write the object to the database, and then create the student object, To add a student object to the Classes object, the other is to create the student object, write the student object to the database, and then create the classes object to add the student object to the Classes object, and the two types of operations are finally different.

3.1 Write the class first and then write the students
after the class is written to the database, the classes object enters the transient state, and a row is written in the database, then the student object is found, and the student object finds the corresponding classes primary key to write it to the table. So the data in the relational model is Non-empty, and the saved code is as follows:

public void Testsave () {session 
  Session=null; 
  try{ 
    //Create Session Object 
    session=hibernateutils.getsession (); 
    Open transaction 
    session.begintransaction (); 
    Create class objects, write class objects to the database 
    Classes classes=new Classes (); 
    Classes.setname ("class"); 
    Session.save (classes); 
    Create the student 1 object and write the student object to the database 
    Student student1=new Student (); 
    Student1.setname ("Zhangsan"); 
    Student1.setclasses (classes); 
    Session.save (student1); 
    Create the Student 2 object and write the student object to the database 
    Student student2=new Student (); 
    Student2.setname ("Lisi"); 
    Student2.setclasses (classes); 
    Session.save (Student2); 
     
    Session.gettransaction (). commit (); 
  catch (Exception e) { 
    e.printstacktrace (); 
    Session.gettransaction (). rollback (); 
  } finally{ 
    Hibernateutils.closesession (session); 
  } 
 

The corresponding list of information written to the database is shown below:

3.2 Write the students first and then write the class
write the students to the database at this time because the student table needs to get the primary key information of the corresponding class column, but because the class information is converted to the transient state, there will be a null value when writing the student information, the code is as follows:

After writing, the corresponding database view is as follows:

Comparing two writes, different results occur because of the sequence of two writes, but because it is a two-way association relationship, there is no exception in writing.

4. Read Operation

Reading data is easy to read compared to writing data, because it is bidirectional, so the data is read in both directions, and you can read information from either end to the other, as follows:

public void TestLoad1 () {session 
  Session=null; 
  try{ 
    session=hibernateutils.getsession (); 
    Session.begintransaction (); 
     
    Reading student information through class 
    Classes classes= (Classes) session.load (classes.class,1); 
    System.out.println ("Classes.name=" +classes.getname ()); 
    Set students=classes.getstudents (); 
     
    For (iterator Iter=students.iterator (); Iter.hasnext ();) { 
      Student student= (Student) Iter.next (); 
      System.out.println ("Student.name=" +student.getname ()); 
    } 
     
    Reading class information through student information 
    Student stu=new Student (); 
    stu= (Student) session.load (Student.class, 1); 
    SYSTEM.OUT.PRINTLN ("Load class information through students classes.id=" +stu.getclasses (). GetId ()); 
    Session.gettransaction (). commit (); 
  catch (Exception e) { 
    e.printstacktrace (); 
    Session.gettransaction (). rollback (); 
  } finally{ 
    Hibernateutils.closesession (session); 
  } 
 

Run the test statement above, generate the corresponding statement information as follows:

Hibernate:select classes0_.id as id1_0_, classes0_.name as name1_0_ from t_classes where classes0_? 
Classes.name=class 
hibernate:select Students0_.classesid as classesid1_, students0_.id as id1_, students0_.id as id0_0_, Students0_.name as name0_0_, Students0_.classesid as classesid0_0_ from T_student students0_ where STUDENTS0_.CLA Ssesid=? 
Student.name=lisi 
Student.name=zhangsan 

Loading class information through students classes.id= 1

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.