创建表关联有两种方式:
-
先创建要关联的表,在创建另外一个表时关联表
-
各自创建表,通过alter table方式关联
一对一关系
一对一有两种方式,外键关联和主键关联
一个球队仅有一个地址,一个地址仅有一个球队
外键关联
// 地址表,地址表是被外键关联的需要先创建
create table address(
address_id int primary key,
city varchar(10),
address varchar(50)
);
// 球队表
create table tem(
team_id int primary key,
team_name varchar(20),
address_id int,
foreign key(address_id) references address(address_id);
);
检验
// 检验外键是否关联成功,外键关联成功如果删除会出现异常
drop table address;
主键关联
// 球队表,球队表是被主键关联的需要先创建
create table team(
team_id int primary key,
team_name varchar(20)
);
// 地址表
// 主键关联必须保证两个表的主键完全一致(包括名称、属性等)
create table address(
team_id int primary key,
city varchar(10),
address varchar(50),
foreign key(team_id) references team(team_id)
);
检验
// 检验主键是否关联成功,主键关联成功如果删除会出现异常
drop table team;
一、一对一、一对多关系
// 班级表
create table grade {
gid int primary key,
gname varchar(20) not null,
gdesc varchar(50)
};
// 学生表
create table student {
sid int primary key,
sname varchar(20) not null,
sex char(2)
gid int
};
// 在学生表添加外键,关联班级表的主键id
alter table student add constraint fk_student_gid foreign key (gid) references grade(gid);
单向一对多关联
-
在数据库中,可以通过添加主外键的关联,表现一对多的关系
-
通过在一方持有多方的集合实现,即在“一”的一端中使用元素表示持有“多”的一端的对象
Grade.class
@Entity
public class Grade implements Serializable {
// @OneToMany指定关联的外键列
@Id
@OneToMany
private int gid;
private String gname;
private String gdesc;
// 班级对学生是一对多的关系,学生对班级是多对一的关系
// “一”的一端持有“多”一端的对象
private Set<Student> students = new HashSet<>();
// 使用Hibernate注解映射,要提供一个无参构造
public Grade() {}
public Grade(int gid, String gname, String gdesc) {
this.gid = gid;
this.gname = gname;
this.gdesc = gdesc;
}
getter and setter...
}
Student.class
@Entity
public class Student implements Serializable {
@Id
private int sid;
private String sname;
private String sex;
public Student() {}
public Student(int sid, String sname, String sex) {
this.sid = sid;
this.sname = sname;
this.sex = sex;
}
gettet and setter...
}
单向多对一关联
-
多对一的关系和关系数据库中的外键参照关系最匹配,即在己方的表中的一个外键参照另一个表的主键
-
通过在多方持有一方的引用实现,需要在“多”的一端使用<many-to_one>配置
@Entity
public class Student implements Serializable {
@Id
private int sid;
private String sname;
// 在多的一方定义一个一方的引用
@ManyToOne
private Gradle grade;
}
二、多对多关系
-
多对多关联也是常见的一种关联关系,如项目和员工之间就是典型的多对多关系
-
多对多关联关系一般采用中间表的形式来实现,即新增一张包含关联双方主键的关联表
-
多对多关联可以使用元素和元素进行配置
学生和课程
// 学生表
create table student(
student_id int primary key,
student_name varchar(10)
);
// 课程表
create table class(
class_id int primary key,
class_name varchar(20)
);
// 中间表使用外键关联方式
create table student_class(
student_id int,
class_id int,
foreign key(student_id) references student(student_id),
foreign key(class_id) references class(class_id)
);
// 测试
insert into student(student_id, student_name) values(1, '小明')
insert into class(class_id, class_name) values(2, '数据库设计')
insert into student_class(student_id, class_id) values(1, 2);
// 三个表同时查询,能从中间表的id中对比获取到另外两个表的信息
select * from student s, class c, student_class sc where s.'student_id'=sc.'student_id' and c.'class_id'=sc.'class_id' and s.'student_name'='小明';
项目和员工
// 项目表
create table project {
proid int primary key,
proname varchar(20) not null
}
// 员工表
create table employee {
empid int primary key,
empname varchar(20)
}
// 关联表
create table proemp {
rproid int,
rempid int
}
// 项目表和员工表之间各自建立外键关联
alter table proemp add constraint fk_rproid foreign key (rproid) references project(proid);
alter table proemp add constraint fk_rempid foreign key (rempid) references employee(empid);
Project.class
@Entity
public class Project {
@Id
private int proid;
private String proname;
private Set<Employee> employees = new HashSet<>();
public Project() {}
getter and setter...
}
@Entity
public class Employee {
@Id
private int empid;
private String empname;
private Set<Project> projects = new HashSet<>();
public Employee() {}
getter and setter...
}