Hibernate多对多关联联合外键创建及其外键表创建

来源:互联网 发布:淘宝美工一般学多久 编辑:程序博客网 时间:2024/06/07 06:17


对于数据表多对多对联只能用外键表进行管理关联关系。在Hibernate中用@ManyToMany(targetEntity=xxx.class)进行定义关联关系。

//映射连接表,指定连接表的表名为xxxx

@JoinTable(name="xxx",

         //映射连接表中名为xxxx的外键列,该列参照当前实体的主键列

         joinColumns=@JoinColumn(name="xxx",referencedColumnName="xxx"),

         //映射连接表中名为xxxx的外键列,指定连接表的关联实体对应表中的xxxx外键列

         inverseJoinColumns=@JoinColumn(name="xxxx",referencedColumnName="xxxx"))

定义关联关系的方式如上所述。

接下来贴出student实体与course实体的代码。这两个实体就是典型的多对多关联。

Stuident实体:

@Entity

@Table(name="student")

public class Student {

         //主键,学号

         @Id@Column(name="stu_num")

         privateString stu_num;

......

@ManyToMany(targetEntity=Course.class)//定义当前实体所有关联的Course实体

         //映射连接表,指定连接表的表名为course_student

         @JoinTable(name="course_student",

                   //映射连接表中名为stu_num的外键列,该列参照当前试题的主键列

                   joinColumns=@JoinColumn(name="stu_num",referencedColumnName="stu_num"),

                   //映射连接表中名为cou_id的外键列,指定连接表的关联实体对应表中的cou_id外键列

                   inverseJoinColumns=@JoinColumn(name="cou_id",referencedColumnName="cou_id"))

         privateSet<Course> course = new HashSet<>();

//省略getter和setter方法

}

 

Course实体:

@Entity

@Table(name="course")

public class Course {

         @Id@Column(name="cou_id")//主键列

         privateString cou_id;

..........

@ManyToMany(targetEntity=Student.class)//定义当前实体所有关联的student实体

         //映射连接表,指定连接表的表名为course_student

         @JoinTable(name="course_student",

                   //映射连接表中名为cou_id的外键列,该列参照当前试题的主键列

                   joinColumns=@JoinColumn(name="cou_id",referencedColumnName="cou_id"),

                   //映射连接表中名为stu_num的外键列,指定连接表的关联实体对应表中的stu_num外键列

                   inverseJoinColumns=@JoinColumn(name="stu_num",referencedColumnName="stu_num"))

         privateSet<Student> student = new HashSet<>();

//省略getter和setter方法

}

 

一般来说,定义了上面两个实体后,当你数据库未创建相关数据表时,Hibernate会自动帮你生成对应的数据表。当然还会自动帮你创建外键表course_student。

如下是运行程序时,Hibenate自动生成数据表的sql语句:

Hibernate:

   create table student (

      stu_num varchar(255) not null,

      ....

       primary key (stu_num)

) ENGINE=InnoDB

 

Hibernate:

   create table course (

       cou_id varchar(255) not null,

           .....

        primary key (cou_id)

   ) ENGINE=InnoDB

 

Hibernate:

   create table course_student (

       evalue varchar(255),

        score float,

        stu_num varchar(255) not null,

        cou_id varchar(255) not null,

        primary key (stu_num, cou_id)

   ) ENGINE=InnoDB

 

Hibernate:

   alter table course_student

       add constraint FKne34exyo39iajeiyhpredxe0j

       foreign key (stu_num)

       references student (stu_num)

 

Hibernate: 

   alter table course_student

       add constraintFKs185u4fs0jmr6y4ty13cgv81u

       foreign key (cou_id)

       references course (cou_id)

 

这样就生成了三张数据表,但是外键表的字段只有相应的外键形成联合主键

 

那么我现在想要外键表添加两个字段,一个是对学生成绩记录的字段,一个是对学生成绩评估的字段。那么通过HIbernate自动生成外键表示不可能达到我们所要的效果的。于是我们所需要做得是,创建多一个实体类CourseStudent,该实体类映射course_student数据表。

然后在该实体中,创建联合主键,映射到对应实体上。然后再添加我们所想要添加的字段。

主要代码如下:

@Entity

@Table(name="course_student")

public class CourseStudent implements Serializable{

         //定义关联student实体

         @ManyToOne(targetEntity=Student.class)

         //映射名为stu_num的外键列,参照student的stu_num列

         @JoinColumn(name="stu_num",referencedColumnName="stu_num")

         @Id

         private Studentstudent;

         //定义关联Course实体

         @ManyToOne(targetEntity=Course.class)

         //映射名为cou_id的外键列,参照COurse的cou_id列

         @JoinColumn(name="cou_id",referencedColumnName="cou_id")

         @Id

         private Course course;

         //学生成绩

         @Column(name="score")

         private float score;

         //学生评价

         @Column(name="evalue")

         private String evalue;

    //无参构造器

         publicCourseStudent(){}

         //初始化全部成员变量的构造器

         publicCourseStudent(Student student,Course course){

                   this.student= student;

                   this.course= course;

         }

         //重写equals()方法,根据student、course判断是否相等

         public boolean equals(Objectobj){

                   if(this ==obj){

                            returntrue;

                   }

                   if(obj !=null && obj.getClass() == CourseStudent.class){

                            CourseStudenttarget = (CourseStudent) obj;

                            returnthis.student.equals(target.getStudent())

                                               &&this.course.equals(target.getCourse())

                                               &&this.score==(target.getScore())

                                               &&this.evalue.equals(target.getEvalue());

                   }

                   returnfalse;

         }

        

         //重写hashCode()方法,根据student、Course计算haseCode值

         public int hashCode(){

                   return(this.course== null ?0:this.course.hashCode())*31*31+

                                     (this.student== null? 0:this.student.hashCode())*31;

         }

//省略getter和setter方法

}

 

因为该实体是联合主键,我们得实现Serializable接口,重写equals()方法和hashCode()方法。

这样一运行程序,Hibernate生成的sql语句中就会有这样的语句:

Hibernate:

    create table course_student (

       evalue varchar(255),

        score float,

        stu_num varchar(255) not null,

        cou_id varchar(255) not null,

        primary key (stu_num, cou_id)

) ENGINE=InnoDB

这就说明我们这样创建外键表对应的实体类是正确的,其Student实体与Course实体关联关系没有改变。

原创粉丝点击