Chen Yaqiang (Cyqcims@mail.tsinghua.edu.cn) Senior Software Engineer October 2003
In the previous article, "Use Hibernate to operate the lasting object", introduce the basic concept of Hibernate, and then demonstrate how to use Hibernate in a web application to encapsulate persistent data objects. However, in a realistic project, we often need to operate multiple data sheets, and there are often complex relationships between multiple tables. In this article, how to describe how many tables in Hibernate, and how to do relation Complex persistent object.
You need the following knowledge and tools before reading this article:
Tomcat 5.09 can be downloaded from www.apache.org; Hibernate 2.0 related operational environments, you can download from http://hibernate.bluemars.net/; at least one database server is installed and there is a related JDBC driver.
Reference information in this article
All code from this article download here
Case introduction
In the first article, we have a simple package for a table. In this article, we discuss more complex situations.
In this example, a one-to-one, one-to-many, multi-to-many cases are considered. As shown in Figure 1.
Figure 1 mapping relationship between the entity
In the above data model diagram, Student is the core of all tables, it and the CLASSES table are a pair of relationships, and the course table is a multi-to-many relationship (link through the student_course_link table), and the address table is one-on-one Relationship.
Through analysis, we can convert the above data model into the following Java persistent object, as shown in Figure 2.
Figure 2 relationship between persistent objects
It can be seen that the data model diagram and the class diagram of the Java persistent object have a very similarity, but it is not exactly the same. For example, the Classes table and the Student table are a couple of relationships; in the class diagram, both are still a couple of relationships, but add a Student property in the CLASSES class. The type of attribute is java.util.set, it Represents all STUDENT objects included in the Classes object.
Create a Hibernate persistent object
The data model has been analyzed, and the lasting object can now be created. The relationship between the persistent object is specified by the class diagram shown in Figure 2.
Let's take a look at the Student class, which is the core of this relationship map, and the code is as shown in routine 1.
Routine 1 Student lasting object (student.java)
Package com.hellking.study.hibernate;
Import java.util.set;
/ **
* The class represents the Students table in Hibernate.
* /
Public Class Student PUBLIC CLASS
{
/ ** Property, and the fields in the Students table correspond to ** /
Private string id;
PRIVATE STRING NAME;
/ ** and other classes between mapping relationships ** /
PRIVATE SET COURSES;
Private classes classes;
Private address address;
/ ** Access method of attributes must be a public method ** /
Public void setid (String String) {
ID = String;
}
Public string getId () {
Return ID;
}
Public void setname (String name)
{
THIS.NAME = Name;
}
Public string getName ()
{
Return this.name;
}
/ ** The relationship between operation and other objects ** /
Public void setcourses (set co) {
THIS.COURSES = CO;
}
Public set getcourses ()
{
Return this.courses;
}
Public Void Setaddress (Address AD)
{
THIS.ADDRESS = Address;
}
Public Address getaddress ()
{
Return this.Address;
}
Public void setClasses (Classes C)
{
THIS.CLASS = C;
}
Public classes getClasses ()
{
Return this.classes;
}
}
In the Student class, because the table of the Students table and Classes is a multi-to-one relationship, it contains a Classes property that type Classes. Its actual significance is that a student can have a class; Students table and Address table is One-on-one relationship, also contains a type of address attribute, its actual meaning is an address; StudentS table and Course are more-to-many relationships, so it contains a type Java.util .Set's Course property, its practical significance is that a student can learn a multi-dochi course, and like a course can be repaired by multiple students.
Classes objects and Student objects are a pair of relationships. The Classes object contains a STUDENTS property that is java.util.set, which is shown in routine 2.
Routines 2 Classes lasting objects (Classes.java)
Package com.hellking.study.hibernate;
Import java.util.set;
/ **
* Represents classes of the Classes table in Hibernate.
* /
Public Class Classes
{
/ ** Property, unanimous of the fields of the classs table ** /
Private string id;
PRIVATE STRING NAME;
/ ** and other classes between mapping relationships ** /
PRIVATE SET STUDENTS;
/ ** Access method of attributes must be a public method ** /
Public void setid (String String) {
ID = String;
}
Public string getId () {
Return ID;
}
Public void setname (String name)
{
THIS.NAME = Name;
}
Public string getName ()
{
Return this.name;
}
/ ** The relationship between operation and other objects ** /
Public void setstudents (SET STUD)
{
THIS.STUDENTS = STUD;
}
Public set getstudents ()
{
Return this.students;
}
}
Course has been introduced in previous articles in the previous article, and it will not be listed here. The Address persistent object is relatively simple. In addition to the properties defined by the table field, it is not introduced into the code in this article.
Describe the relationship between objects
Now we have written a long-lasting object, the following tasks are to describe the relationships between them. First we look at the description of the Student persistent object, as shown in routine 3.
Routine 3 Student's Description (Studient.hbm.xml)
XML Version = "1.0"?>
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
Name = "com.hellking.study.hibernate.student" Table = "students" Dynamic-update = "false" > Name = "id" Column = "studentid" TYPE = "string" Unsaved-value = "any" > id> Name = "name" TYPE = "string" Update = "true" INSERT = "True" COLUMN = "Name" /> Name = "coursees" Table = "student_course_link" Lazy = "false" INVERSE = "false" Cascade = "all" Sort = "unsorted" > Column = "studentid" /> Class = "com.hellking.study.hibernate.course" COLUMN = "courseid" Outer-join = "auto" /> set> Name = "classes" Class = "com.hellking.study.hibernate.classes" Cascade = "none" Outer-join = "auto" Update = "true" INSERT = "True" Column = "classesid" /> Name = "Address" Class = "com.hellking.study.hibernate.address" Cascade = "none" Outer-join = "auto" Constrained = "false" /> clas> hibernate-maping> Three relationships are described in the Student.hbm.xml descriptor. The first is a one-on-one relationship between Student and Address. It is the simplest relationship, uses: To describe, the name here is an attribute that the name address in the Student object; the class represents the type of Address property: com.hellking.study.hibernate.Address. Next, look at many-to-one relationship between Student and Classes, use: To describe it. Similarly, Name is indicated by the attribute of the name Classes in the Student object; the class represents the type of the classes property, and the column represents the external key name used by the Student table references the CLASSES table. Correspondingly, the Student class is also referenced in the CLASSES class, which uses the following descriptors to describe this relationship: Name = "students" Table = "students" Lazy = "false" INVERSE = "false" Cascade = "all" Sort = "unsorted" > Column = "classesid" /> Class = "com.hellking.study.hibernate.student" /> set> When describing multiple-to-many relationships between Student and Course, the following methods are used: Name = "coursees" Table = "student_course_link" Lazy = "false" INVERSE = "false" Cascade = "all" Sort = "unsorted" > Column = "studentid" /> Class = "com.hellking.study.hibernate.course" COLUMN = "courseid" Outer-join = "auto" /> set> When mapping multiple-to-many relationships, you need to use a link table. The name of this table is specified by the Table property, and the linked table contains two fields: courseid and studentid. The following description: Specifies the external key of the Student object in the Student_Course_LINK link table. Correspondingly, the following descriptors are used in the Course persistent object to describe this relationship: Name = "students" Table = "student_course_link" lazy = "false" INVERSE = "false" Cascade = "all" Sort = "unsorted" > COLUMN = "courseid" /> Class = "com.hellking.study.hibernate.student" Column = "studentid" Outer-join = "auto" /> set> Since the description of other persistent objects is basically, it will be listed here, please refer to the source code of this article. Don't forget to add a description of these objects in hibernate.cfg.xml. Use mapping relationship Below we develop a simple instance to test this mapping. The most frequent operation of persistent objects is to increase data, query data, delete data, and update data. For updating data, the operation of multiple tables and individual tables are not different, and it is not exemplified here. Add data to the database We are here to test the first three operations, first to see the case where data to the database, as shown in routine 4. Routine 4 Test the image of mapping between persistent objects (some code of maptestBean.java) / ** * Add data in the database * / Public Void Adddata (String StudentID, String Classesid, String Courses) Throws HibernateException { Try { / ** * The following code adds a Student, specified for Student * Address, Coursetes and Classses. * / Begintransaction (); // Create a Student object. STUDENT = new student (); Student.setName ("Hellking2"); Student.SetId (StudentID); // Create an Address object. Address Addr = new address (); Addr.SetCity ("beijing"); Addr.SetState ("bj"); Addr.SetStreet ("TSINGHUA"); Addr.Setzip ("100083"); Addr.SetId (student.getid ()); // Set the relationship between Student and Address. Student.Setaddress (AddR); SET set = new hashset (); SET.ADD (Student); // Create a COURSE object. Course course = new course (); Course.setId (Coursesid); Course.setname ("Computer_JSP"); / / Set the relationship between Course and Student objects. Course.SetStudents (SET); // Create a CLASSES object. Classes cl = new classes (); Cl.setID (ClassesID); Cl.setname ("Engine Power"); / / Set the Students object included in a CLASSES object. Cl.setstudents (SET); // Due to the two-way relationship, the Student object also needs to be set once. Student.SetClasses (CL); / / Save the created object into the session. Session.save (CL); Session.save (course); Session.save (student); Session.save (AddR); // Submit a transaction to take effect. EndTransaction (TRUE); } Catch (HibernateException E) { System.out.println ("" When adding data! "); E.PrintStackTrace (); Throw e; } } In routine 4, the various properties of the persistent object are first set before adding data to the database, such as: Student.setName ("Hellking2"); This way of setting attributes and normal classes have no difference. After setting all the properties, set the relationship between persistent objects, such as: Student.Setaddress (AddR); If there is a multiple relationship between objects, you may need to save the object in the set collection and then set, such as: SET set = new hashset (); SET.ADD (Student); Course.SetStudents (SET); When all the properties and object relationships are set, you can call: Session.save (PersistentObject); The method is saved to the Hibernate session. Finally, call EndTransaction to submit transactions and turn off the Hibernate session. data query In complex entity object mapping, it is often queried more complicated. As a demonstration, we also provide several query methods, as shown in routine 5. Routine 5 Test the query data of mapping between persistent objects (some code of MapTestBean.java) / ** * Get the address information of a given StudentID of the STUDENT * / Public Address GetDress (String ID) Throws HibernateException { Begintransaction (); Student ST = (student) session.load (student.class, id); Address Addr = (address) session.load (address (address.class, st.getid ()); EndTransaction (FALSE); Return addr; } / ** * Get all courses for a given StudentID of Student * / Public Set getCourses (String ID) THROWS HIBERNATEXCEPTION { Begintransaction (); Student ST = (student) session.load (student.class, id); EndTransaction (FALSE); Return st.getcourses (); } / ** * Test Classes * / of the Student belonging to a given StudentID Public classes getClasses (String ID) throws HibernateException { Begintransaction (); Student ST = (student) session.load (student.class, id); System.out.println (st.getClasses (). GetId ()); EndTransaction (FALSE); Return st.getClasses (); } Here is three kinds of query methods, namely: Query the STUDISS information of the given ID; all COURSES information for the STURSS for a given ID; query the class content of the STUDENT of the given ID. In the query, first create a Hibernate session object using the Begintractions () method and start a new Hibernate transaction; then get a STUDENT object for a given ID through the session.Load () method, such as: Student ST = (student) session.load (student.class, id); Finally call the Student.Getxxx () method to return to the specified object. delete data When the relationship between the table is more complicated, to delete data, there is often a case where the cascade deletion is exist, and the case is more complicated because the level of the cascade is more complicated, and it is not exemplary here. Suppose we want to delete all related records of the Student object of a given ID, you can use the methods shown in routine 6. Routine 6 Test Delete Data (MapTestBean.java section) / ** * Remove all information related to a student * (Here is just testing, we don't talk about what this operation is). * / Public void deltestud (String ID) throws HibernateException { Begintransaction (); Student ST = (student) session.load (student.class, id); Address Addr = (address) session.load (address (address.class, st.getid ()); // Delete Address information. Session.delete (AddR); // Delete the classes information. Session.delete (st.getclasses ()); / ** * Delete Course one by one. * / Iterator it = st.getcourses (). iterator (); it.hasnext ();) { Course c = (course) it.next (); Session.delete (c); } // Finally, delete the Student object. Session.delete (ST); EndTransaction (TRUE); } Similarly, before performing the deletion, first create a new Hibernate session and a new Hibernate transaction, then click the object load you want to delete, and then call the session.delete () method to delete the specified object. If you want to delete an object in a collection, you can delete one by one, such as the method of deleting Courses in routine 6. test Here is a program for tested MapTestBean in JSP, see maptest.jsp files. Before performing tests, make sure that the connection database is complete, and there is no error in each persistent object. If the configuration is difficult, please refer to the source code of this article. let's move After two articles learned from shallow to profound, I hope to play the role of pouring bricks, I believe that readers have a holistic grasp of Hibernate. Hibernate is gradually widely used in enterprise application development due to its ease of use and good graft. Hibernate official website provides a very good manual, you can refer to it. If you are not proficient in JDBC and don't want to learn it, consider using hibernate; if you have difficulty in using the persistent framework like entity beans, maybe Hibernate can help you! Reference The source code of this article is downloaded here. Http://www.apache.org Download Tomcat. Hibernate's official website, http://hibernate.bluemars.Net/, contains the latest information on Hibernate. Hibernate Chinese Forum, hibernate.fankai.com contains more than Hibernate. The Hibernate discussion site, www.jdon.com, the warm discussion of Hibernate, JDO, CMP, etc. 1: http://www.jdon.com/jive/thread.jsp? Forum = 16 & three = 6062 & start = 0 & msrange = 15 On the warm discussion of Hibernate, JDO, CMP, 2: http://www.theserverside.com/discussion/thread.jsp? Thread_id = 19732Hibernate2 Reference Documentation, you can get, very good reference information from Hibernate official website. Hibernate In Action, a very professional Hibernate reference book, the main developer of the Hibernate project, GAVIN KING, MANNING Publishing House. You can get some chapters of this book from http://www.theserverside.com.