(14)学生、分数、课程【一对多,多对多练习】

这里写图片描述
需求:通过分数可以找到课程,通过分数可以找到学生,通过学生可以找到课程。
分析关系映射:
一个学生,对应多个分数(一个分数只属于一个学生),根据需求,应该在分数中设manytoone
一个课程,会有多个成绩(一个成绩只属于一个课程),根据需求,应该在分数中设manytoone
一个学生会有多门课程,一个课程也会有多个学生,因为不要求课程中找到所有的学生,所以在学生端设manytomany。
在数据库中是主外键的关系,在类中是对象的关系。
在之前的学生和课程中,因为没有考试分数的要求,所以利用manytomany会生成中间表,但是这里有分数的要求,所以要有类score。
还有一点需要注意,就是manytomany必然会生成中间表。首先不考虑manytomany。考虑manytoone
依据下面的写法生成的表和属性名
student :id name
score 中有:id course_id student_id sc 【因为通过@JoinColumn进行了重命名 】主键是id
course:id name
当有了manytomany后,因为必然生成中间表【当@ManyToMany
@JoinTable(name=”score1”,
joinColumns={@JoinColumn(name=”student_id”)},inverseJoinColumns={@JoinColumn(name=”course_id”)}
)//将会以上两个字段为联合主键,并不是以id为主键,所以在这种情况应该先建好表 】
当生成的中间表的表名是score1与score无关时,没有关系,但是现实不会这样设计。
当name=score时,说明生成的中间表和对象实体名相同,则会将manytoone中的表属性和manytomany中的表属性都会放在里面,当manytoone的外键名和中间表的属性名不同时,会产生冗余字段,当将两者的属性名设为相同时,就会将相同的字段去掉,但是此时的主键是中间表形成的联合主键,而不是id,若要让hibernate自动生成表,还想让id为主键,则手动改数据库中的表。

@Entity
public class student {

    private int id;
    private String name;
    //private Set<score> scores=new HashSet<score>();
    private Set<course> cs=new HashSet<course>();

    @Id
    @GeneratedValue
    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;
    }
    //@OneToMany(mappedBy="s")//一个学生会有多门成绩,一个成绩记录只属于一个学生,所以学生和成绩是一对多。
    //@JoinColumn(name="sId")
    /*
    public Set<score> getScores() {
        return scores;
    }
    public void setScores(Set<score> scores) {
        this.scores = scores;
    }
    */
    //多对多将字段写在中间表中
    @ManyToMany//思考过程:需要的操作是:通过学生能够导航到课程,但不要求课程导航到学生
    @JoinTable(name="score",
    joinColumns={@JoinColumn(name="studen_id")},inverseJoinColumns={@JoinColumn(name="cours_id")}
    )//将会以上两个字段为联合主键,并不是以id为主键,所以在这种情况应该先建好表

    public Set<course> getCs() {
        return cs;
    }
    public void setCs(Set<course> cs) {
        this.cs = cs;
    }


}
@Entity 

public class score {

    private int id;
    private course c;
    private student s;
    private int sc;//课程成绩

    /*
     * 面向对象的设计,score属于哪个学生的,score属于哪个课程的
     */

    @ManyToOne//许多成绩属于一个学生。
    @JoinColumn(name="student_id")
    public student getS() {
        return s;
    }
    public void setS(student s) {
        this.s = s;
    }



    @Id
    @GeneratedValue
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }


    @ManyToOne//多个成绩属于一个课程
    @JoinColumn(name="course_id")
    public course getC() {
        return c;
    }
    public void setC(course c) {
        this.c = c;
    }
    public int getSc() {
        return sc;
    }
    public void setSc(int sc) {
        this.sc = sc;
    }   
}
@Entity 

public class course {

    private int id;
    private String name;
    //private Set<score> scs=new HashSet<score>();


    @Id //必须加在getId上面
    @GeneratedValue
    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;
    }
    //@OneToMany(mappedBy="c")//一个课程会有多个成绩。一个成绩只对应一个课程,所以叫一对多
    //@JoinColumn(name="cId")
    /*
     * public Set<score> getScs() {

        return scs;
    }
    public void setScs(Set<score> scs) {
        this.scs = scs;
    }

    */  
}
posted @ 2017-11-14 10:14  测试开发分享站  阅读(92)  评论(0编辑  收藏  举报