Hibernate关系一般分成这么几种情况:一对一单向,一对一双向,一对多单向,多对一单向,一对多双向,多对一双向,多对多单向,多对多双向。
1:一对一单向
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
@OneToOne
@JoinColumn(name="wife")//定义字段名称..
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
public class Wife {
private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
create table Husband (id integer not null auto_increment, name varchar(255), wife integer, primary key (id))
create table Wife (id integer not null auto_increment, name varchar(255), primary key (id))
alter table Husband add index FKAEEA401BAECA6750 (wife), add constraint FKAEEA401BAECA6750 foreign key(wife) references Wife (id)
2:一对一双向
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
@OneToOne
@JoinColumn(name="wife")//定义字段名称..
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
public class Wife {
private int id;
private String name;
private Husband husband;
@OneToOne(mappedBy="wife")
//双向外键关联需要设置mappedBy,否则会有冗余
//其中"wife"为Husband的get方法中的wife,还不是那个wife字段。
public Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
不要忘了mappedBy,否则会生成两个外键关联。
其实单向和双向生成的表没什么区别,区别只是单向的时候只能由一方获得另外一方,而双向则是每一方都能获得对方。
create table Husband (id integer not null auto_increment, name varchar(255), wife integer, primary key (id))
create table Wife (id integer not null auto_increment, name varchar(255), primary key (id))
alter table Husband add index FKAEEA401BAECA6750 (wife), add constraint FKAEEA401BAECA6750 foreign key (wife) references Wife (id)
3:多对一
@Entity
@Table(name="t_group")
public class Group {
private int id;
private String name;
@Id
@GeneratedValue
@Column(name="group_id")
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;
}
}
@Table(name="t_user")
public class User {
private int id;
private String name;
private Group group;
@ManyToOne
@JoinColumn(name="id_group")
public Group getGroup() {
return group;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setGroup(Group group) {
this.group = group;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
多对一外键关联的表设计是把一那一方的id放在多的那一方表中,如果反过来则会产生冗余。
create table t_group (group_id integer not null auto_increment, name varchar(255), primary key (group_id))
create table t_user (id integer not null auto_increment, name varchar(255), id_group integer, primary key (id))
alter table t_user add index FKCB63CCB6102EF96C (id_group), add constraint FKCB63CCB6102EF96C foreign key (id_group) references t_group (group_id)
4:一对多
@Table(name="t_group")
public class Group {
private int id;
private String name;
private Set<User> users;
@Id
@GeneratedValue
@Column(name="group_id")
public int getId() {
return id;
}
@OneToMany
@JoinColumn(name="group_id")
//不要忘了joinColumn,否则会认为是多对多的一种,会生成一张中间表.
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
@Table(name="t_user")
public class User {
private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
create table t_group (group_id integer not null auto_increment, name varchar(255), primary key (group_id))
create table t_user (id integer not null auto_increment, name varchar(255), group_id integer, primary key (id))
alter table t_user add index FKCB63CCB6411589EC (group_id), add constraint FKCB63CCB6411589EC foreign key (group_id) references t_group (group_id)
如果没有@JoinColumn(name="group_id"),那么会怎么样呢?
create table t_group (group_id integer not null auto_increment, name varchar(255), primary key (group_id))
create table t_group_t_user (t_group_group_id integer not null, users_id integer not null, primary key (t_group_group_id, users_id), unique (users_id))
create table t_user (id integer not null auto_increment, name varchar(255), primary key (id))
alter table t_group_t_user add index FKCFE61C612E429AD7 (t_group_group_id), add constraint FKCFE61C612E429AD7 foreign key (t_group_group_id) references t_group (group_id)
alter table t_group_t_user add index FKCFE61C619EBDBBAB (users_id), add constraint FKCFE61C619EBDBBAB foreign key (users_id) references t_user (id)
它会生成一张中间表。当作是多对多。
5:多对多单向
public class Teacher {
private int id;
private String name;
private Set<Student> students;
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
@ManyToMany
@JoinTable(
name="t_s",
joinColumns={
@JoinColumn(name="teacherId")},
inverseJoinColumns={@JoinColumn(name="studentId")}
)
//如果不加@JoinTable,那么中间关系表属性就是teachersidd, studentsid。而JoinTable就是为了改变这个名称的。
public Set<Student> getStudents() {
return students;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setStudents(Set<Student> students) {
this.students = students;
}
}
public class Student {
private int id ;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
create table Student (id integer not null auto_increment, name varchar(255), primary key (id))
create table Teacher (id integer not null auto_increment, name varchar(255), primary key (id))
create table t_s (teacherId integer not null, studentId integer not null, primary key (teacherId, studentId))
alter table t_s add index FK1BF6883117471 (teacherId), add constraint FK1BF6883117471 foreign key (teacherId) references Teacher (id)
alter table t_s add index FK1BF68E56AEE3 (studentId), add constraint FK1BF68E56AEE3 foreign key (studentId) references Student (id)
如果不加@JoinTable,其实也没关系。结果如下:
create table Student (id integer not null auto_increment, name varchar(255), primary key (id))
create table Teacher (id integer not null auto_increment, name varchar(255), primary key (id))
create table Teacher_Student (Teacher_id integer not null, students_id integer not null, primary key (Teacher_id, students_id))
alter table Teacher_Student add index FK55FA429E1052676F (students_id), add constraint FK55FA429E1052676F foreign key (students_id) references Student (id)
alter table Teacher_Student add index FK55FA429E57018E8C (Teacher_id), add constraint FK55FA429E57018E8C foreign key (Teacher_id) references Teacher (id)
差别并不是很明显,只是一个名称上的区别:students_id(我们想象应该是student_id)和studentId(我们自定义的)。
其实还有几种没写,全是双向的,我只是写出了一对一的双向,其他的也差不多。