Hibernate關系映射之many-to-many


1、建表

2、創建實體類及映射文件

Student.java類

 1 public class Student implements java.io.Serializable {
 2 
 3     // Fields
 4 
 5     private Integer sid;
 6     private String sname;
 7     private Set<Teacher> teachers=new HashSet<Teacher>();  8 
 9     // Constructors
10 
11     /** default constructor */
12     public Student() {
13     }
14 
15     /** full constructor */
16     public Student(String sname) {
17         this.sname = sname;
18     }
19 
20     // Property accessors
21 
22     public Integer getSid() {
23         return this.sid;
24     }
25 
26     public void setSid(Integer sid) {
27         this.sid = sid;
28     }
29 
30     public String getSname() {
31         return this.sname;
32     }
33 
34     public void setSname(String sname) {
35         this.sname = sname;
36     }
37 
38     public Set<Teacher> getTeachers() { 39         return teachers; 40     }
41 
42     public void setTeachers(Set<Teacher> teachers) { 43         this.teachers = teachers; 44     }
45 }

使用多對多注解應該是:

 @ManyToMany @JoinTable(name="teacher_student",joinColumns={@JoinColumn(name="sid")},inverseJoinColumns={@JoinColumn(name="tid")}) public Set<Teacher> getTeachers() { return teachers; }

Teacher.java類

 1 public class Teacher implements java.io.Serializable {
 2 
 3     // Fields
 4 
 5     private Integer tid;
 6     private String tname;
 7     private Set<Student> students=new HashSet<Student>();  8 
 9     // Constructors
10 
11     /** default constructor */
12     public Teacher() {
13     }
14 
15     /** full constructor */
16     public Teacher(String tname) {
17         this.tname = tname;
18     }
19 
20     // Property accessors
21 
22     public Integer getTid() {
23         return this.tid;
24     }
25 
26     public void setTid(Integer tid) {
27         this.tid = tid;
28     }
29 
30     public String getTname() {
31         return this.tname;
32     }
33 
34     public void setTname(String tname) {
35         this.tname = tname;
36     }
37 
38     public Set<Student> getStudents() { 39         return students; 40     }
41 
42     public void setStudents(Set<Student> students) { 43         this.students = students; 44     }
45 }

被控方注解是:

    @ManyToMany(mappedBy="teachers") public Set<Student> getStudents() { return students; }

Student.hbm.xml

<hibernate-mapping>
    <class name="com.db.Student" table="student" catalog="mydb">
        <id name="sid" type="java.lang.Integer">
            <column name="sid" />
            <generator class="native" />
        </id>
        <property name="sname" type="java.lang.String">
            <column name="sname" length="32" />
        </property>
        <!-- 通過table屬性告訴hibernate中間表,cascade指明級聯操作的類型,inverse屬性說明Student實體類是主控方,負責維護關系表 --> 
        <set name="teachers" table="teacher_student" cascade="save-update,delete" inverse="false">
        <!-- 通過key屬性告訴hibernate在中間表里面查詢sid值相應的student記錄 --> 
            <key>
                <column name="sid" not-null="true" />
            </key>
             <!-- 通過column項告訴hibernate對teacher表中查找tid值相應的teacher記錄 --> 
            <many-to-many class="com.db.Teacher" column="tid"/>
        </set>
    </class>
</hibernate-mapping>

Teacher.hbm.xml

<hibernate-mapping>
    <class name="com.db.Teacher" table="teacher" catalog="mydb">
        <id name="tid" type="java.lang.Integer">
            <column name="tid" />
            <generator class="native" />
        </id>
        <property name="tname" type="java.lang.String">
            <column name="tname" length="32" />
        </property>
        <!-- 通過table屬性告訴hibernate中間表,cascade指明級聯操作的類型,inverse屬性說明Teacher實體類是被控方,不負責維護關系表 ,不能觸發對象和數據庫的同步更新的。-->
        <set name="students" table="teacher_student" inverse="true" cascade="save-update,delete">
            <key>
                <column name="tid" not-null="true" />
            </key>
            <many-to-many class="com.db.Student" column="sid" />
        </set>
    </class>
</hibernate-mapping>

hibernate.cfg.xml

<hibernate-configuration>

    <session-factory>
        <property name="dialect">
            org.hibernate.dialect.MySQLInnoDBDialect
        </property>
        <property name="connection.url">
            jdbc:mysql://localhost:3306/mydb
        </property>
        <property name="connection.username">root</property>
        <property name="connection.password">123456</property>
        <property name="connection.driver_class">
            com.mysql.jdbc.Driver
        </property>
        <property name="myeclipse.connection.profile">
            MyDBAccount
        </property>
        <property name="show_sql">true</property>
        <mapping resource="com/db/Student.hbm.xml" />
        <mapping resource="com/db/Teacher.hbm.xml" />
    </session-factory>

</hibernate-configuration>

3、建立測試用例

測試用例一:

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Session session=HibernateSessionFactory.getSession();
        Student stu1=new Student();
        stu1.setSname("StudentAmy");
        Teacher t1=new Teacher();
        t1.setTname("TeacherSusan");
        Teacher t2=new Teacher();
        t2.setTname("TeacherLily");
        Teacher t3=new Teacher();
        t3.setTname("TeacherMaike");
        Set<Teacher> teachers=new HashSet<Teacher>();
        teachers.add(t1);
        teachers.add(t2);
        teachers.add(t3);
        stu1.setTeachers(teachers);
        session.save(stu1);
        session.getTransaction().commit();
    }

對應的SQL語句是:

Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)

測試用例二:

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Session session=HibernateSessionFactory.getSession();
        Student stu1=new Student();
        stu1.setSname("StudentJhon1");    
        Student stu2=new Student();
        stu2.setSname("StudentLihua1");
        Teacher t1=new Teacher();
        t1.setTname("TeacherJay1");
        t1.getStudents().add(stu1);
        t1.getStudents().add(stu2);
        session.beginTransaction();
        session.save(t1);
        session.getTransaction().commit();
    }

}

對應的SQL語句是:

Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.student (sname) values (?)

測試用例三:

    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Session session=HibernateSessionFactory.getSession();
        Student stu1=new Student();
        stu1.setSname("StudentJhon1");    
        Student stu2=new Student();
        stu2.setSname("StudentLihua1");
        Teacher t1=new Teacher();
        t1.setTname("TeacherJay1");
        t1.getStudents().add(stu1);
        t1.getStudents().add(stu2);
 stu2.getTeachers().add(t1);
        session.beginTransaction();
        session.save(t1);
        session.getTransaction().commit();
    }

}

對應的SQL語句是:

Hibernate: insert into mydb.teacher (tname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into mydb.student (sname) values (?)
Hibernate: insert into teacher_student (sid, tid) values (?, ?)

通過測試用例發現,兩個實體類都進行了級聯操作,但是只有將Teacher實體對象添加到Student的teachers屬性集合中時才能更新維護中間表。因為Student中的teachers集合的inverse屬性是false,使得Student類成為主控方,負責維護關聯關系;而Teacher中的students集合的inverse屬性為true,使得Teacher類成為被控方,不會維護關聯關系。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM