zoukankan      html  css  js  c++  java
  • 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类成为被控方,不会维护关联关系。

  • 相关阅读:
    一卡通应用系统解决方案
    2013524 项目一
    射频RFID系统
    SIM操作系统
    python中eval, exec, execfile,和compile [转载]
    FastJSON学习
    坑爹的UICollectionView
    8位单片机编程的一些坑
    Android DownloadThread.run()学习
    蓝牙接收苹果手机通知 ANCS协议分析
  • 原文地址:https://www.cnblogs.com/SaraMoring/p/5638495.html
Copyright © 2011-2022 走看看