zoukankan      html  css  js  c++  java
  • Hibernate学习(五)Hibernate 多对多映射

    说到多对多关系,印象最深刻的就是大学的选修课。一个学生可以选修多门课程,一门课程可以有多个学生选修,学生所选的每一门课程还有成绩。这个场景的E-R图如下:

    对于多对多的关系,我们通常会抽出一张中间表(连接表),来负责维护这两张表的多对多关系,比如上述关系应该生成的表结构为:

    PO对象

       Student.java

    package entity;
    
    import java.util.Set;
    
    public class Students {
        private int id ;
        private String name;
        private Set<Course>courses;
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Set<Course> getCourses() {
            return courses;
        }
        public void setCourses(Set<Course> courses) {
            this.courses = courses;
        }
        
    }

    Course.java

    package entity;
    
    import java.util.Set;
    
    public class Course {
       private int id;
       private String name;
       private Set<Students> students;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<Students> getStudents() {
        return students;
    }
    public void setStudents(Set<Students> students) {
        this.students = students;
    }
       
    }

    映射文件

    Students.hnm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name ="entity.Students" table="t_students">
           <id name="id">
              <generator class="native"/>
           </id>
           <property name="name"/>
           <set name="Courses" table="t_singup">
            <key column="student_id"/>
             <!-- 多个学生id对应对个course_id -->
    <many-to-many class="entity.Course" column="course_id"></many-to-many> </set> </class> </hibernate-mapping>

    配置文件中的set对应于相应类中的集合,key是指向多的一方的外键,对应t_score表中的course_id。

    Course.hbm.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="entity.Course" table="t_course">
        <id name="id">
          <generator class="native"/>
        </id>
        <property name="name"/>
        <set name="students" table="t_signup" inverse="true">
         <key column="course_id"/>
         <many-to-many class="entity.Students" column="student_id"/>
        </set>
        </class>
    </hibernate-mapping>    

    运行代码执行的建表语句为:

    drop table  t_course
    drop table  t_signup
    drop table  t_students
    
    create table t_course (id integer primary key , name varchar(255));
    create sequence course
    minvalue 1  --最小值
    nomaxvalue  --不设置最大值
    start with 1 --从1开始计数
    increment by 1 --每次加1个
    nocycle  --一直累加,不循环
    nocache --不建缓冲区
    create  or replace trigger course_tg
    before insert on t_course for each row when(new.id is null)
    begin
    select course.nextval into:new.id from dual;
    end;
    create table t_signup (student_id integer , course_id integer ,constraint zhujian primary key (student_id, course_id));
    drop sequence students;
    create table t_students (id integer , name varchar(255), primary key (id));
    create sequence students
    minvalue 1  --最小值
    nomaxvalue  --不设置最大值
    start with 1 --从1开始计数
    increment by 1 --每次加1个
    nocycle  --一直累加,不循环
    nocache ;--不建缓冲区
    create  or replace trigger students_tg
    before insert on t_students for each row when(new.id is null)
    begin
    select students.nextval into:new.id from dual;
    end;
    create index FK7DADC3438FFF3382 on t_signup(student_id);
    alter table t_signup add constraint FK7DADC3438FFF3382 foreign key(student_id) references t_students(id);
    create index FK7DADC3438CBEF332  on t_signup(course_id);
    alter table t_signup add constraint  FK7DADC3438CBEF332 foreign key(course_id) references t_course(id);

    生成的表结构如下:

    t_signup中生成了复合主键,student_id和course_id分别是指向t_students和t_course的外键。

    插入测试

    session.beginTransaction();
    
    Course course1=new Course();
    course1.setName("《心理应激微反应》");
    session.save(course1);
    Course course2=new Course();
    course2.setName("《哈利·波特与遗传学》");
    session.save(course2);
    Course course3=new Course();
    course3.setName("《三国杀攻略教程》");
    session.save(course3);
    Course course4=new Course();
    course4.setName("《寄生虫与寄生虫病视频欣赏》");
    session.save(course4);
    
    Student student1=new Student();
    Set courses1=new HashSet();
    courses1.add(course1);
    courses1.add(course2);
    student1.setCourses(courses1);
    student1.setName("小胡");
    session.save(student1);
    
    Student student2=new Student();
    Set courses2=new HashSet();
    courses2.add(course3);
    courses2.add(course4);
    student2.setCourses(courses2);
    student2.setName("小玉");
    session.save(student2);
    
    Student student3=new Student();
    Set courses3=new HashSet();
    courses3.add(course1);
    courses3.add(course2);
    courses3.add(course3);
    courses3.add(course4);
    student3.setCourses(courses3);
    student3.setName("小洋");
    session.save(student3);
    
    session.getTransaction().commit();

    插入结果:

      但是上述方法并不适合给多对多的关系添加额外的属性,那怎么办呢?可以用两个一对多关系来实现,即可以手动将中间表设计成一个实体,并为其配置映射关系,所以通常情况下,一个多对多关系也可以用两个一对多关系来实现。

  • 相关阅读:
    走进AngularJs(二) ng模板中常用指令的使用方式
    mysql知识汇总
    存储动态数据时,数据库的设计方法
    js判断密码强度
    svg―Raphael.js Library(一)
    常用js代码
    IE6实现图片或背景的圆角效果
    巧用css border
    IE6下的效果
    理解盒模型
  • 原文地址:https://www.cnblogs.com/daweige/p/8044054.html
Copyright © 2011-2022 走看看