There are often relationships between objects in life, such as one-to-one, one to many, many to many. For example, there are many students in a Course class who are one to many. In the database, you can add a foreign key to the Student table to point to the class id to indicate that the Student contains multiple Student relationships. Correspondingly, in Java, you can create two classes, Course and Student, to represent the class and Student. How to establish the relationship between them?
The courses table and students table in the database are as follows
One to many mapping
The first is a one to many mapping, such as establishing a mapping from a class ("one") to a Student ("many"). You can add a Set collection in the Course class to hold multiple Student objects, and Set Course to point to Student in hibernate.
Add Hibernate database mapping to the two classes in IDEA, the CourseEntity class, StudentEntity class file and corresponding hbm.xml mapping file will be generated automatically, and registration will be completed in hibernate.cfg.xml file. Then manually add the Set attribute students and its get/set method in CourseEntity
public class CoursesEntity { private int id; private String name; private Integer hours; private Set<StudentEntity> students=new HashSet<StudentEntity>(); ...... public Set<StudentEntity> getStudents() { return students; } public void setStudents(Set<StudentEntity> students) { this.students = students; }
Then you need to modify the CourseEntity.hbm.xml file, add the set attribute students, specify the corresponding data table and the foreign key associated with the data table courses, as well as the Java entity class corresponding to the attribute
<class name="entity.CoursesEntity" table="courses" schema="test"> <id name="id" column="id"/> <property name="name" column="name"/> <property name="hours" column="hours"/> <set name="students" table="students"> <!--To configure students Table corresponding to set--> <key column="course_id"></key> <!--Corresponding foreign key in the table--> <one-to-many class="entity.StudentEntity"/> <!--Corresponding Java class--> </set> </class>
After that, create a course course object in the test method, and two student objects s1 and s2, and call add() of Set in the students collection of the course to add two student objects, and finally save these objects in the database. Note that Junit test unit is still used here, so the creation and shutdown of session and factory are completed in previous setup and tearDown.
@Test void testCourse(){ //Create course and student objects CoursesEntity course=new CoursesEntity(2,"Data Structure",72); StudentEntity s1=new StudentEntity(1003,"Xiao Ming",15); StudentEntity s2=new StudentEntity(1004,"Floret",14); //Add two student objects to the Set set of students in the course course.getStudents().add(s1); course.getStudents().add(s2); //Save course and student objects to database session.save(course); session.save(s1); session.save(s2); }
Viewing the database, it can be seen that the corresponding courses have been added in the course table, and not only two students have been added in the students table, but also their foreign key course ﹣ id points to the corresponding course id
It is also very convenient to view the data. You can traverse the selected students through the Set set returned by course, and hibernate will automatically retrieve the corresponding student information from the students table
@Test void findCourse() { CoursesEntity course = session.load(CoursesEntity.class, 2); System.out.println("Course Name:"+course.getName()); //Return student Set set through course to traverse student information Set<StudentEntity> students = course.getStudents(); System.out.println("Course students:"); for (StudentEntity student : students) System.out.print(student.getId() + ':' + student.getName()); }
Delete a student from the course. By calling the remove() method of Set, the database will automatically change the foreign key of the student course ﹣ ID to null
CoursesEntity course = session.load(CoursesEntity.class, 2); Set<StudentEntity> students = course.getStudents(); //Get the Set set of course students StudentEntity s=session.load(StudentEntity.class,1003); //Get the specified Student object //Delete the specified student from the course selection list students.remove(s); session.save(s); //Save operation
Bidirectional mapping
In addition to configuring the Course to Student mapping, you can also configure the Student to Course mapping. This enables two-way mapping between two object types. Map Student - > Course as follows:
First, add the variable course and get/set method to the StudentEntity class to represent the course property
public class StudentEntity { private int id; private String name; private Integer age; private Address address; private CoursesEntity course; //Add attribute representing the course ...... public CoursesEntity getCourse() { return course; } public void setCourse(CoursesEntity course) { this.course = course; }
Then configure the "multi" hbm.xml file, with name as the variable name, class as the pointed class, and column as the foreign key in the data table
<class name="entity.StudentEntity" table="students" schema="test"> <id name="id" column="id"/> <property name="name" column="Name"/> <property name="age" column="Age"/> <component name="address" class="entity.Address"> <property name="city" column="city"/> <property name="street" column="street"/> </component> <!--To configure Student point Course Mapping--> <many-to-one name="course" class="entity.CoursesEntity" column="course_id"/> </class>
Next, create the Course and Student objects in the code and map them in two directions
@Test void testCourse() { //Create course and student objects CoursesEntity course = new CoursesEntity(2, "Data Structure", 72); StudentEntity s1 = new StudentEntity(1003, "Xiao Ming", 15); StudentEntity s2 = new StudentEntity(1004, "Floret", 14); //Add course - > student mapping course.getStudents().add(s1); course.getStudents().add(s2); //Add student - > Course mapping s1.setCourse(course); s2.setCourse(course); //Save course and student objects to database session.save(course); session.save(s1); session.save(s2); }
Maintain bi-directional mapping: through the above operations, the bi-directional mapping of the data table is realized, but look at the HIbernate execution statement as shown below. After two insert operations of the students table, two update operations are performed. This is because the force insert operation is performed when Course maintains the one to many relationship, and then the update operation is performed when student maintains the many to one relationship, which is unnecessary and affects the execution efficiency. It is obvious that this is because both parties are maintaining one to many relationships. Therefore, we want only one party to maintain one to many relationships. In the Course configuration file, set the inverse property of set to false, which means that the relationship is maintained by the "many" party.
Hibernate: insert into courses (name, hours, id) values (?, ?, ?) Hibernate: insert into students (Name, Age, city, street, course_id, id) values (?, ?, ?, ?, ?, ?) Hibernate: insert into students (Name, Age, city, street, course_id, id) values (?, ?, ?, ?, ?, ?) Hibernate: update students set course_id=? where id=? Hibernate: update students set course_id=? where id=?
Cascade operation: when saving objects through session, we not only execute session.save(course), but also execute session.save(s1) to save students. The Course object already contains students, which should be saved together automatically instead of manually saving. This requires cascade operation to set. You can configure the set in the Course configuration file, and set the cascade property as follows
Set inverse and cascade as follows:
<class name="entity.CoursesEntity" table="courses" schema="test"> <id name="id" column="id"/> <property name="name" column="name"/> <property name="hours" column="hours"/> <!--Yes inverse,cascade Property to set--> <set name="students" table="students" inverse="false" cascade="save-update"> <key column="course_id"></key> <one-to-many class="entity.StudentEntity"/> </set> </class>