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 }

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 }

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类成为被控方,不会维护关联关系。

时间: 2024-07-31 14:42:52

Hibernate关系映射之many-to-many的相关文章

Java学习笔记-Hibernate关系映射

1. 初识Hibernate——关系映射 http://blog.csdn.net/laner0515/article/details/12905711 2. Hibernate 笔记8 关系映射1(多对一,一对多): http://www.cnblogs.com/zilong882008/archive/2011/11/05/2236559.html 3. Hibernate关联映射 http://www.cnblogs.com/huxi/archive/2009/12/15/1624988.

hibernate 关系映射文件配置

<!--Department.hbm.xml users属性,本类与User的一对多 --> <set name="users"> <key column="departmentId"></key> <one-to-many class="User" /> </set> <!-- parent属性,本类与Department(上级)的多对一 --> <man

浅谈Hibernate关系映射(3)

继上篇博客 一对多关联映射(单向) 上面我们介绍了多对一,我们反过来看一对多不就是多对一吗?那还用再进行不同的映射吗?有什么差别吗?一对多和多对一映射原理是一致的,存储是相同的,也就是生成的数据库的表是一样的,他们之间不同的是维护的关系不同. 他们之间不同点是维护的关系不同 *多对一维护的关系是:多指向一的关系,有了此关系,加载多的时候可以将一加载上来. *一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来. 一个班级有多个学生,通过班级可以看到学生信息. Class

浅谈Hibernate关系映射(2)

继上篇博客 一对一关系映射:一对一关联映射在实际生活中是比较常见的,如人与身份证的关系,通过人这个对象可以找到他相关的内容. 一对一单向(主键): 单向一对一主键关联,靠的是它们的主键相等,从Person中能看到IdCard,也就是把t_idCard中的主键拿过来当做t_Pseron的主键. 如图的线表示一个关联,在person中可以看见idcard.即在person中持有idCard的引用 person类的映射关系 <hibernate-mapping> <class name=&qu

浅谈Hibernate关系映射(4)

继上篇博客 多对多关联映射(单向) 多对多对象关系映射,需要加入一张新表完成基本映射. Hibernate会自动生成中间表 Hibernate使用many-to-many标签来表示多对多的关联,多对多的关联映射,在实体类中,跟一对多一样,也是用集合来表示的. 如下图所示 通过User可以查看Role的信息 User的映射文件 <hibernate-mapping> <class name="com.bjpowernode.hibernate.User"> <

Hibernate关系映射基础

1.  Hibernate关系映射基础 1.1.  Doctype <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 指定根元素和dtd文件的命名空间. 1.2.  hibernate-mapping <hiberna

hibernate关系映射(一对一)

一对一关联分为外键关联和主键关联:外键关联是指从表中存在主表的外键,这也是一种特殊的多对一关系:主键关联是指主从表的id一致 外键关联 主表:IDCard(校园卡) 从表:Student(学生) 学生类的定义和hbm文件的配置如下 1 public class Student { 2 private int id; 3 private String name; 4 //持有idcard的外键 5 private IDCard idCard; 6 }  可以看到 学生持有校园卡外键的类结构和之前多

hibernate关系映射(多对多)

多对多关系(学生Student,课程Course) 学生类的定义以及hbm文件的配置如下 1 public class Student { 2 private int id; 3 private String name; 4 private Set<Course> courses = new HashSet<Course>(); 5 } 1 <?xml version="1.0" encoding="UTF-8"?> 2 <

hibernate关系映射(多对一)

对多一关系是最普遍也是最重要的一种对象关系,其中又包括了单向的多对一,单向的一对多以及双向的多对一关系 单向多对一 多的一方:学生(Student) 一的一方:班级(Grade) 班级类的定义以及hbm文件配置如下 1 public class Grade { 2 private int id; 3 private String name; 4 } 1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTY

Hibernate关系映射(一) 基于外键的单向一对一

模拟用户和地址的映射关系,一个用户只有一个地址,用户知道地址,但是地址不知道用户.用户对地址的单向一对一映射. 一.建立实体类 Account.cs类 package com.lxit.entity; import java.io.Serializable; public class Account implements Serializable{ public Account(){ } private int id; private String name; private String pa