The design and implementation of the relationship between the students, curriculum and scores of Hibernate learning Note 12
This horse soldier Teacher's Hibernate video study a topic, here to use many-to-many, many-to-one relationship and joint primary key, so feel very good, write the article blog record.
Consider database tables first
1. Student table: For simplicity, only the student ID and student name are considered, where the ID is the primary key
2. Curriculum: For simplicity, only the course ID and course name are considered, where the ID is the primary key
3. Score Table
There are two kinds of solutions to the score table
3.1 The first one is: Using federated primary keys: student_id and course_id
3.2 Second: Do not use the federated primary key, but use the ID as the primary key
Here, this blog post takes the second approach: by not using the Federated primary key, using the ID as the primary key
In considering entity classes, and their mapping relationships
A student can choose multiple courses, and a course can be chosen by multiple students, i.e. students and courses are a many-to-many relationship. And a student can have multiple scores, so the score and the student is a many-to-one relationship, the same as the score and the course is a many-to-one relationship.
Start the design below
There are many-to-many relationships between the student entity and the course class, but, in general, we need to get all of his courses through the students, so we need such a guide, and sometimes we need to take the course to extract the students who choose this course, so we build a two-way association.
Student class
@Entity Public class Student { Private intIdPrivateString name;/* * Student and Course are many-to-many relationships, * because we generally need to get course through student, without having to course to get student, * so we build a one-way guide * */
PrivateSet<course> courses=NewHashset<course> ();@ManyToMany(Cascade=cascadetype.all)//Set the intermediate table, the intermediate table must have the same name as score @JoinTable(name ="Score", Joincolumns =@JoinColumn(name="student_id"), Inversejoincolumns =@JoinColumn(name="course_id") ) PublicSet<course>getcourses() {returnCourses } Public void setcourses(set<course> courses) { This. courses = courses; }@Id @GeneratedValue(strategy = Generationtype.auto) Public int getId() {returnId } Public void setId(intID) { This. id = ID; } PublicStringGetName() {returnName } Public void SetName(String name) { This. name = name; }}
Course Class
@Entity Public class Course { Private intIdPrivateString name;PrivateSet<student> students=NewHashset<student> ();@ManyToMany(mappedby="Courses") PublicSet<student>getstudents() {returnStudents } Public void setstudents(set<student> students) { This. Students = students; }@Id @GeneratedValue(strategy = Generationtype.auto) Public int getId() {returnId } Public void setId(intID) { This. id = ID; } PublicStringGetName() {returnName } Public void SetName(String name) { This. name = name; }}
Score Class
Score and student, course are many-to-one relationship, so we need to establish the relationship between Manytoone.
@Entity@Table(name="Score") Public class score { Private intId/* * Score and student, course are many-to-one relationship, * and student, course is a many-to-many relationship * * * PrivateStudent Student;PrivateCourse Course;Private intScore;@Id @GeneratedValue Public int getId() {returnId } Public void setId(intID) { This. id = ID; }@ManyToOne @JoinColumn(name="student_id") PublicStudentgetstudent() {returnStudent } Public void setstudent(Student Student) { This. student = student; }@ManyToOne @JoinColumn(name="course_id") PublicCourseGetCourse() {returnCourse } Public void Setcourse(Course Course) { This. course = course; } Public int Getscore() {returnScore; } Public void SetScore(intScore) { This. score = score; }}
This completes the design of the entity class.
Test
You can observe the build statement by following the code below.
public voidtestSchema(){ new StandardServiceRegistryBuilder().configure().build(); new MetadataSources(serviceRegistry).buildMetadata(); new SchemaExport(); schemaExport.create(EnumSet.of(TargetType.DATABASE), metadata); }
The table statement is as follows:
As can be seen from the table statement, the generated score table is the combined primary key of student_id and course_id, and in the score entity class, we are using @id to decorate the id,hibernate and do not follow the @id to make the table, Instead, they are generated based on the intermediate table score of the student class and the course entity class.
Since the generated table is not compatible with our purpose, so we can choose to manually build the table with the following statement:
Test the Save method, which is the persisted object
There is a student who has studied two courses and has two grades.
@Testpublic void Testsave () {/ * * There was a student who took a course and had a result * */Student s1=new Student ();S1. SetName("WU");Course c1=new Course ();C1. SetName("Math");Course c2=new Course ();C2. SetName("中文版"); / * Confusion: Add the following two statements to two insert into score values (Null,null); * */S1. Getcourses(). Add(C1);S1. Getcourses(). Add(C2);Score Sc1=new score ();Sc1. SetScore(98);Sc1. Setstudent(S1);Sc1. Setcourse(C1);Score Sc2=new score ();Sc2. SetScore( the);Sc2. Setstudent(S1);Sc2. Setcourse(C2);To open a transaction for persistence Session s=sessionfactory. Getcurrentsession();S. BeginTransaction();S. Save(S1); S. Save(C1); S. Save(C2); S. Save(SC1);S. Save(SC2); S. Gettransaction(). Commit();}
The result of the correct persistence in the database results in the following:
In the test, when we add the following two lines of code in the test code (these two lines of code are commented out in the code block above),
s1.getCourses().add(c1);s1.getCourses().add(c2);//这两行代码的意图就是将课程加入到学生中
You will get the following result: We automatically generate two rows of NULL row data.
Problem encountered: Field ' id ' doesn ' t has a default value
In the process of completing this test, the following problems were encountered:
The reason is that when we manually build the table, no auto_increment is set for the primary key ID.
The design and implementation of the relationship between the students, curriculum and scores of Hibernate learning Note 12