需求:通过分数可以找到课程,通过分数可以找到学生,通过学生可以找到课程。
分析关系映射:
一个学生,对应多个分数(一个分数只属于一个学生),根据需求,应该在分数中设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;
}
*/
}