Java【教程】多表关系
之前学习了JDBC,请见之前写的一篇教程:Java【教程】Java数据库连接:JDBC
在这篇教程里,我们学会了用Java代码操作单表。
在学数据库的时候,我们知道多个表之间可能是存在关系的,可以分为:一对多、多对一、一对一和多对多,怎么用JAVA代码实现多表关系操作呢?这就是本篇教程的内容。
1.一对多关系,多对一关系
表
学生表和年级表就是一对多关系:一个年级可以有多名学生,但反过来一名学生只属于一个年级。学生是多方,年级是一方。
注意:一对多关系、多对一关系,是相对而言的。学生表对年级表,是多对一;年级表对学生表,是一对多。虽然关系是相对而言的,要看谁对谁,但谁是多方、谁是一方,这个是确定的,学生是多方,年级是一方。
创建学生表、年级表,并插入数据:
create table student (
stuid int primary key,
stuname varchar(5),
stuage int,
gid int
);
create table grade(
gradeid int primary key ,
gname varchar(5)
);
insert into grade values(1,'一年级');
insert into grade values(2,'二年级');
insert into grade values(3,'三年级');
insert into student values(1,'张三',18,1);
insert into student values(2,'李四',14,2);
insert into student values(3,'富贵',13,3);
insert into student values(4,'王芳',17,1);
insert into student values(5,'甜甜',15,2);
实体类(bean)
MVC,M(模型)-V(视图)-C(控制器),规定封装数据的JavaBean(又叫:实体类):
- 对应于数据库中的一张表
- 表名=类名,列名=属性名
- a. public修饰的类,提供public 无参构造方法
- b. 所有属性 都是private
- c. 提供getter和setter方法
Student类:
public class Student {
private int stuid;
private String stuName;
private int stuAge;
private int gid;
@Override
public String toString() {
return "Student{" +
"stuid=" + stuid +
", stuName='" + stuName + '\'' +
", stuAge=" + stuAge +
", gid=" + gid +
'}';
}
public int getStuid() {
return stuid;
}
public void setStuid(int stuid) {
this.stuid = stuid;
}
public String getStuName() {
return stuName;
}
public void setStuName(String stuName) {
this.stuName = stuName;
}
public int getStuAge() {
return stuAge;
}
public void setStuAge(int stuAge) {
this.stuAge = stuAge;
}
public int getGid() {
return gid;
}
public void setGid(int gid) {
this.gid = gid;
}
}
Grade类:
public class Grade {
private int gradeId;
private String gname;
public int getGradeId() {
return gradeId;
}
public void setGradeId(int gradeId) {
this.gradeId = gradeId;
}
public String getGname() {
return gname;
}
public void setGname(String gname) {
this.gname = gname;
}
}
实体类通过属性来建立两表关系
数据表:通过外键列来维系两表关系,实体类:通过属性来维系两表关系。
后者怎么实现呢?
一方存多方的集合or多方存一方的对象,选择其中一种方式即可:
方式1:
在Grade类中,有一个属性是Student类的集合。(体现了一对多关系,年级表对学生表)
方式2:
在Student类中,有一个属性是Grade类的对象。(体现了多对一关系,学生表对年级表)
在开发中,往往同时选择这两种方式。
选哪种方式?
要看具体的任务,
如果任务是利用一对多关系进行查询,就使用方式1;
如果任务是利用多对一关系进行查询,就使用方式2。
如:
一对多关系:根据年级id,查询所有该年级的学生,选择方式1
select * from grade g,student s where s.gid=g.gradeid and g.gradeid=?
多对一关系:查询所有学生,及其对应年级的信息,选择方式2
select * from grade g,student s where s.gid=g.gradeid
方式1:一方存多方的集合(体现了一对多关系)
方式1:在Grade类中,有一个属性是Student类的集合。(体现了一对多关系,年级表对学生表)
Grade类新增代码:
private List<Student> studentList;
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
Dao层接口:
public interface GradeDao {
//查询某个年级信息(要求:展示年级名称和学生列表)
public Grade getGradeById(int id);
}
Dao层的实现类:
该类的作用是实际操作数据库。
写这个类之前,要做好以下准备工作:
1.把数据库相关的jar包放到lib文件夹,并在Idea里进行配置将lib设置为project library
2.创建util包,里边放DruidUtil.java,这是使用Druid连接池的工具类
3.Druid.properties放到src文件夹下,这个配置文件里的数据库名字需要改一下
这个类要做什么事情?
1.用sql语句从数据库中查询出若干条数据
2.根据查询出的数据,创建Grade对象
3.根据查询出的数据,创建Student对象
4.通过属性的赋值(把一个对象添加到另外一个对象的属性中),完成实体类对于多表关系的维系
5.return主体类的对象(所谓主体类,就是“一对多”的“一”,或者“多对一”的“多”)
对于方式1,即一方存多方的集合(体现了一对多关系),该类完成了以下事情:
1.用sql语句从数据库中查询出若干条数据
2.根据查询出的数据,创建1个Grade对象
3.根据查询出的数据,创建若干个Student对象
4.一方存多方的集合,将Student对象的集合,赋值给Grade对象的属性
5.return Grade对象
public class GradeDaoImpl extends DruidUtil implements GradeDao {
@Override
public Grade getGradeById(int id){
//这里创建年级对象的操作要放在循环外,因为只需要创建一个年级对象即可
Grade grade = new Grade();
List