java学习 学生管理系统-v2.0

本次将使用三层架构来对上次的学生管理系统-v1.0进行改进。

三层架构

  • 视图层,通常用于与用户交互,收集用户输入的信息,或展示信息;
  • 业务层,通常做业务逻辑处理,在学习期间,业务层往往是代码最少的;
  • 持久层,通常只做与数据增删改查相关的操作;

对应的包结构

  • 视图层,controller;
  • 业务层,service;
  • 持久层,dao;

其中还包括 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;
}

小结

老师管理系统与学生管理系统相似度很高,就不继续写了。

三层就是,视图层处理用户交互,即输入输出操作,之后把工作交给业务层完成。之后业务层把操作数据的具体工作交给持久层完成。