本次将使用三层架构来对上次的学生管理系统-v1.0进行改进。
对应的包结构:
其中还包括 domain 存放模型类;entry 程序入口;utils 工具类
首先我们对先前的学生管理系统进行一些升级,将老师管理系统加入变成一个新的信息管理系统。在这里就以学生管理系统为例,老师管理系统跟学生管理系统步骤一样,就不做介绍。
创建entry包,再其中建立InfoManagerEntry类来编写程序入口,再main方法中用输出语句创建主菜单,用户输入后调用StudentController对象的start方法进入学生管理系统。
public class InfoManagerEntry {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (true) {
//主菜单
System.out.println("----------------------------------------");
System.out.println("* 欢迎来到黑马管理系统 *");
System.out.println("* 1 学生管理 *");
System.out.println("* 2 教师管理 *");
System.out.println("* 3 退出系统 *");
System.out.println("----------------------------------------");
System.out.print("请输入选择:");
int num = sc.nextInt();
switch (num) {
case 1:
//调用start方法进入学生管理系统
StudentController studentController = new StudentController();
studentController.start();
break;
case 2:
break;
case 3:
System.out.println("退出管理系统,感谢您的使用。");
System.exit(0);//推出虚拟机
default:
System.out.println("输入有误,请重新输入!");
break;
}
}
}
}
首先创建domain包,建立Student类,包含学号、姓名、年龄、生日字段,并且创建有参无参沟槽方法和get/set方法。
public class Student {
private Integer id;
private String name;
private Integer age;
private String birthday;
public String toString() {
return id + "\t" + name + "\t" + age + "\t" + birthday;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public Student(Integer id, String name, Integer age, String birthday) {
this.id = id;
this.name = name;
this.age = age;
this.birthday = birthday;
}
public Student() {
}
}
学生管理系统入口在StudentController中,由main方法中调用start方法进入。在其中创建start方法,用输出语句创建学生管理系统主菜单,根据用户输入后调用功能方法进入各个功能。
public void start() {
Scanner sc = new Scanner(System.in);
while (true) {
System.out.println("----------------------------------------");
System.out.println("* 欢迎来到学生管理系统 *");
System.out.println("* 1 添加学生 *");
System.out.println("* 2 删除学生 *");
System.out.println("* 3 修改学生 *");
System.out.println("* 4 查看学生 *");
System.out.println("* 5 退出系统 *");
System.out.println("----------------------------------------");
System.out.print("请输入选择:");
int num = sc.nextInt();
switch (num) {
case 1:
addStudent();
break;
case 2:
delStudent();
break;
case 3:
editStudent();
break;
case 4:
findStudent();
break;
case 5:
System.out.println("退出学生管理系统,感谢您的使用");
return;
default:
System.out.println("输入有误,请重新输入!");
break;
}
}
}
此处与之前版本的管理系统不同的是视图层只与用户打交道,把具体的操作数据的任务交给业务层,让业务层去找持久层完成数据的添加功能。
视图层只负责把用户的输入提交给业务层,并把业务层的返回的结果输出给用户,完成与用户的交互。
业务层对象StudentService studentService = new StudentService();
在StudentController的成员变量中声明
private void addStudent() {
Integer id;
while (true) {
System.out.print("请输入学号:");
id = sc.nextInt();
boolean flag = studentService.isExists(id);
if (flag) {
System.out.println("该学号已存在!");
} else {
break;
}
}
//调用用户输入方法
Student student = input(id);
studentService.addStudent(student);
}
学生信息的添加功能需要先调用业务层的isExists方法查找用户输入的学号是否已存在,该方法当存在用户输入的学号时,遍历学生列表,判断在列表中的学生对象id与用户输入的id是否一致,返回一个布尔值,不存在则返回false,存在返回true,因此可以用其判断学号是否被占用
public boolean isExists(Integer id) {
ArrayList<Student> stus = studentDAO.findAllStudent();
for (int i = 0; i < stus.size(); i++) {
//判断在stus中索引为i的学生对象的id与用户输入的id是否一致
if (stus.get(i).getId().equals(id)) {
return true;
}
}
return false;
}
在业务层中实现isExists方法,调用持久层的findAllStudent方法查询出所有学生并返回结果,目前的业务层负责的业务仅仅是传递信息
数据逐层return到Controller,便可以返回值判断是否继续添加输入信息
当用户输入一个未被占用的学号时,StudentController的addStudent方法继续执行,为了方便,我把用户输入的数据封装Student对象的部分提取成一个方法input
public Student input(Integer id) {
System.out.print("请输入姓名:");
String name = sc.next();
System.out.print("请输入年龄:");
Integer age = sc.nextInt();
System.out.print("请输入生日:");
String birthday = sc.next();
Student student = new Student(id, name, age, birthday);
return student;
}
之后StudentController的addStudent方法会调用StudentService的addStudent传递Student实例给业务层,让业务层完成判断添加是否成功的工作,并告知是否添加成功
public void addStudent(Student stu) {
boolean flag = studentDAO.addStudent(stu);
if (flag) {
System.out.println("添加成功");
} else {
System.out.println("添加失败");
}
}
在业务层的addStudent方法中,调用持久层的addStudent方法,完成数据添加
public boolean addStudent(Student stu) {
return list.add(stu);
}
对视图层来说,查看学生功能需要从业务层获取到所有学生的集合,然后遍历集合逐一打印到控制台。并且当集合为空的时候,给用户打印额外的提示信息
private void findStudent() {
ArrayList<Student> allStudent = studentService.findAllStudent();
if (allStudent.size() == 0) {
System.out.println("暂无学生,请先添加学生");
} else {
System.out.println("学号\t姓名\t年龄\t生日");
for (int i = 0; i < allStudent.size(); i++) {
System.out.println(allStudent.get(i).toString());
}
}
}
业务层找持久层要集合对象,即:在业务层的findAllStudent方法中调用持久层的findAllStudent方法获取集合对象
public static ArrayList<Student> findAllStudent() {
return studentDAO.findAllStudent();
}
在持久层中,直接返回集合对象
public ArrayList<Student> findAllStudent() {
return list;
}
逐层返回数据到视图层,视图层便可向用户打印输出
至此,查看学生的功能就实现完成了
对视图层来说,删除学生需要判断用户输入的学号是否存在,若存在则删除,不存在则提示用户
其中判断用户输入的学号是否存在的逻辑,基本同添加学生功能的判断用户输入的学号是否存在的逻辑一致。调用的都是同一个方法获取返回值,然后再根据返回值判断。不同的只是判断的条件不一致
private void delStudent() {
Integer id;
Scanner sc = new Scanner(System.in);
while (true) {
System.out.print("请输入要删除的id:");
id = sc.nextInt();
boolean exists = studentService.isExists(id);
if (!exists) {
System.out.println("该id不存在,请重新能输入。");
} else {
break;
}
}
studentService.delStudent(id);
}
之后StudentController的delStudent方法会调用StudentService的delStudent传递用户输入的id给业务层,让业务层完成判断删除是否成功的工作,并告知是否删除成功
public void delStudent(Integer id) {
boolean flag = studentDAO.delStudent(id);
if (flag) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
}
在业务层的delStudent方法中,调用持久层的delStudent方法,完成数据删除
public boolean delStudent(Integer id) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getId().equals(id)) {
return list.remove(list.get(i));
}
}
return false;
}
对视图层来说,修改学生需要判断用户输入的学号是否存在,若存在则修改信息,不存在则提示用户
其中判断用户输入的学号是否存在的逻辑,基本同添加学生功能的判断用户输入的学号是否存在的逻辑一致。调用的都是同一个方法获取返回值,然后再根据返回值判断。不同的只是判断的条件不一致
private void editStudent() {
Scanner sc = new Scanner(System.in);
Integer id;
while (true) {
System.out.print("请输入要修改的学生id:");
id = sc.nextInt();
boolean exists = studentService.isExists(id);
if (exists) {
break;
} else {
System.out.println("该id不存在,请重新输入。");
}
}
Student student = input(id);
studentService.editStudent(student);
}
之后StudentController的eidtStudent方法会调用StudentService的editStudent传递Student实例给业务层,让业务层完成判断修改是否成功的工作,并告知是否修改成功
public void editStudent(Student student) {
boolean flag = studentDAO.editStudent(student);
if (flag) {
System.out.println("修改成功");
} else {
System.out.println("修改失败");
}
}
在业务层的editStudent方法中,调用持久层的editStudent方法,完成数据修改
public boolean editStudent(Student newStu) {
for (int i = 0; i < list.size(); i++) {
Student stu = list.get(i);
if (stu.getId().equals(newStu.getId())) {
stu.setName(newStu.getName());
stu.setAge(newStu.getAge());
stu.setBirthday(newStu.getBirthday());
return true;
}
}
return false;
}
老师管理系统与学生管理系统相似度很高,就不继续写了。
三层就是,视图层处理用户交互,即输入输出操作,之后把工作交给业务层完成。之后业务层把操作数据的具体工作交给持久层完成。