Hibernate (vii) __ One or one-to-many, one-to-one, Many-to-many

Source: Internet
Author: User

1.many-to-one

Take the relationship between students and departments as an example:

Department.hbm.xml

package = "com.xidian.domain" ><classclass= "identity" ></generator></ Id><property name= "name" type= "java.lang.String" ><column name= "name" length= "" "not-null=" True "/></property></class>

Student.hbm.xml

 <?xml version= "1.0" encoding= "utf-8"? ><! DOCTYPE hibernate-mapping Public "-//hibernate/hibernate mapping DTD 3.0//en" "http://hibernate.sourceforge.net/ HIBERNATE-MAPPING-3.0.DTD ">package  =" Com.xidian.domain "><class  name=" Student "><id name=" ID "type=" Java.lang.Integer "> <generator class  =" Identity "></generator> </id><property name= "name" type= "java.lang.String" ><column name= "name" length= "up"/></   Property><!--column   = "dept_id" indicates the foreign key name of the future automatically generated table --><many-to-one name= "dept" column= "dept_id"/ ></class  >

Application:

Student stu1=new Student ();
Stu.setname ("song jiang");

Student stu2=new Student ();
Stu.setname ("song jiang");

Department d=new Department ();
D.setname ("finance department");

Stu1.setdept (d);//specify which department the student is

Stu2.setdept (d);

S.save (d);
S.save (stu1);
S.save (stu2);
It is also possible to save the student Re-save department first . The department does not exist when the student is saved, the foreign key is set to empty, and then the department is saved, when commit commits the transaction

When they are found to have mappings, they will then set the Student's foreign key reference (in which case hibernate will have one more UPDATE statement ).

When applying a many-to-one scenario, you will find that only the many to one single-direction mapping can be added to a department through a foreign-key relationship with multiple students .

question: in turn, if you need to pass a department number (1)to get all the students in that department? If you use the many to one form above, you need the HQL statement to query :

String hql= "from Student where dept.id=1"

In this case, you need to one-to-many the opposite direction query .

The concept of lazy loading is introduced here:

Summary : When querying a multi-table query, when we query an object, by default , only the normal properties of the object are returned , and when the user goes to use the object properties ,

will issue a second query to the Database. . This phenomenon we call Lazy phenomena .

student= (student) s.get (student.class, 3);

System.out.println (student1.getname () + "department ="
+student1.getdept (). GetName ());//when The session is still in, you can still send SQL statements to the Database. But if we just get the student object,

The object property is not queried, and when the session is closed it is no longer possible to send SQL statements to the database and cannot be queried.

Workaround :

1. Display initialization proxy object hibernate.initized (student.getdept ())

2. Modify the object relationship file class property lazy rewrite lazy=false

3. Through the filter (web Project ) Opensessioninview (as can be seen from the above example, when the session is closed, you cannot send SQL statements to the database, then expand the scope of the session

This will be explained in detail later)

2.one-to-many

Configure <set ></set> on one side

On the many side must have a foreign key to point to one of the properties of this side, so configuration <many-to-one> is necessary.

and The one side is configured <one-to-many> See if you need to specify a collection property to point back to many One side, it is very convenient to get the attributes from the table from the primary table Side.

Look here again by getting to the department to view student information :

Department department1= (Department) s.get (department.class, 3);
Remove students from the department
set<student> stus= Department1.getstus ();
For (Student Ss:stus) {
System.out.println (ss.getname ());

}

add students
department Department=new Department ();
department.setname ("business unit");

student stu1=new Student ();
stu1.setname ("shunping");
student stu2=new Student ();
stu2.setname ("xiaoming");

set<student> sets=new hashset<student> ();
sets.add (stu1);
sets.add (stu2);
department.setstus (sets);

s.save (department);              //this involves cascading operations , you need to configure the

in Department.hbml.xml

<set name= "stus" cascade= "save-update" > This will save the department when the

The students in the department are Saved.

3.one-to-one

There are two ways of The difference is that based on the primary key, a mapping relationship is formed between the primary key

(a property from a table is both a primary key of its own table and a foreign key referencing to another table, and the primary key acts as a foreign key), which is based on a foreign key that is a non-primary key that forms a mapping relationship.

(1) one -to-one based on primary key

be sure to set constrained="true " to form a foreign key constraint relationship

A typical problem in a one-to-ones relationship is the relationship between people and identity cards.

Person P1=new Person ();
P1.setid (1224);
P1.setname ("xkj");

Idcard idcard=new Idcard ();
Idcard.setvalidatedte (new Date ());

Idcard.setperson (p1);//indicates that the Idcard object belongs to the P1 Object.
P1.setidcard (idcard); Wrong way
S.save (p1); Save People First
S.save (idcard);

Results in Database:

Idcard table

Person table

Here are two things to note :

1. If I use P1.setidcard (idcard) to specify a relationship between person and idcard, an error occurs:

You can only use Idcard.setperson (p1) Mode. The relationship should be that there is a foreign key on the idcard that points to person, not the other way around. Error line in

Description when saving idcard, the foreign key person property is empty and causes an Error.

2. If you change the save Order:

S.save (idcard); Save the card first

S.save (p1);

To report an error:

Java.sql.SQLException: [microsoft][sqlserver Driver for jdbc][sqlserver]

The INSERT statement conflicts with the FOREIGN KEY constraint "fkb8cdf6cb2a59f864". The conflict occurred in the Database "test", table "dbo.person", column ' ID '.  
Analytic theory: foreign key constraints, such as B table there is a field b, there is a foreign key constraint, cited for a table of the primary key a, then in the table B to insert data,

Field B must be a value that already exists in table a, such as a value that is not in a in a to b, and a foreign key constraint is Reported.

But if you look back one-to-many that example, but found that the student table has a foreign key to the Department's primary key, It is also possible to save the student Re-save department,

Just one more update statement, which is the optimization mechanism of Hibernate. But it's not allowed in this place, why?

I hope you are pointing pits!

(ii) one-to-one based on foreign keys

Only change the IdCard.hbm.xml mapping file above

<id name= "id" type= "java.lang.Integer" >

<generator class= "assigned"/>

</id>

<property ame= "vaidatedate" type= "java.util.Date" >

<column name= "validatedate"/>

</property>

<many-to-one name= "person" unique= "true"/> //person is the foreign key that will be born into this foreign key in the idcard table, It points to the primary key ID of the primary table

On Idcard side, can be regarded as a special case of many-to-one, plus unique guarantee Unique.

Person P1=new Person ();
P1.setid (122);
P1.setname ("xkj");

Idcard idcard=new Idcard ();
Idcard.setid (1905);
Idcard.setvalidatedte (new Date ());

Idcard.setperson (p1);//indicates that the Idcard object belongs to the P1 Object.

S.save (p1);//save People First
S.save (idcard);

Database results:

Here I still test the two problems that appear before:

The first question is not an error, only the Idcard person foreign key is Empty.

The second problem is that Hibernate is solved again, and the same is a more update statement.

4.many-to-many

Students and courses are classic and Many-to-many Cases.

In actual development, if there is a many-to-many relationship, we should convert it to two one-to-many or many-to-on, this program is good control, and there is no redundancy.

In stucourse, there are two foreign keys pointing to student and course, respectively.

Add a student, a course, an elective course
Student stu1=new Student ();
Stu1.setname ("xiao ming");

Course course=new Course ();
Course.setname ("java");

Stucourse sc=new Stucourse ();

Sc.setcourse (course);
Sc.setstudent (stu1);

Saved Sequentially.
S.save (stu1);
S.save (course);
S.save (sc);

Database results:

Hibernate (vii) __ One or one-to-many, one-to-one, Many-to-many

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.