Hibernate 一对一、一对多、多对多关系

创建表关联有两种方式:

  • 先创建要关联的表,在创建另外一个表时关联表

  • 各自创建表,通过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...	
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值