JavaSE高级程序设计总结、训练——集合的基本使用方法总结4(一个小项目)

JavaSE程序设计训练4:以文件模拟数据库完成管理系统

一、项目需求:

需要写一个学生管理系统,这个管理系统不能用数据库,要用文件IO完成数据库的所有功能。功能如下:

1.1、功能1:描述

每次系统启动的时候,完成一次从外存到内存的读取,说白了就是完成数据库的启动,把外存(长期保持)的数据读取到可以进行逻辑操作的内存上!

1.2、功能1:实现(只展示核心代码)

	public void getDataFromFileToMem() throws Exception {
    
    
        BufferedReader br = new BufferedReader(
                new InputStreamReader(
                        new FileInputStream(new File("StudentOfFiles\\StudentInfo.txt")),
                        "UTF-8"
                )
        );
        String strLine = null;
        while((strLine = br.readLine()) != null){
    
    
            strLine = strLine.replaceAll(" {2,}", " ");
            String[] splitArray = strLine.split("\\ |\\t");
            if(splitArray.length != 4){
    
    
                throw new Exception("读取信息有误!");
            }
            else{
    
    
                myStudents.add(new Student(splitArray[0], splitArray[1],
                        Integer.parseInt(splitArray[2]), Integer.parseInt(splitArray[3])));
            }
        }
        br.close();
    }

1.3、功能2:描述

完成系统的增删改查,所谓增删改,都必须同步内外存,既要在内存数据结构上处理,也要在外存上处理,要达到同步!所谓查询,就要输入一个学号,在控制台输出该学生的信息。

1.4、功能2:实现(只展示核心代码)

增加学生:
	public void insertStudent(Student s) throws IOException {
    
    
        myStudents.add(s);
        BufferedWriter bw = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(file, true),
                        "UTF-8"
                )
        );
        String strLine = new String(s.getName() + "\t" + s.getId() + "\t" + s.getAge() + "\t" + s.getScore());
        bw.write(strLine + "\t\n");
        bw.flush();
        bw.close();
    }
删除学生:
	private static void cmdOfRemoveStudent(StudentDatabaseOperate sdo, Scanner sc){
    
    
        System.out.println("----------------请输入您要删除的学生的学号:----------------");
        String id = "";
        while(true) {
    
    
            id = sc.next();
            if(!"".equals(id)){
    
    
                break;
            }
        }
        int len = sdo.getSize(), pos = -1;
        for(int i = 0;i < len;++i){
    
    
            if(id.equals(sdo.getMyStudents().get(i).getId())){
    
    
                pos = i;
                break;
            }
        }
        try {
    
    
            if(-1 != pos){
    
    
                sdo.getMyStudents().remove(pos);
            }
            else{
    
    
                throw new IOException("error");
            }
            exit(sdo, true);
            sdo.filterByScore(true);
        } catch (IOException e) {
    
    
            System.out.println("文件内容删除有误!");
        }
    }
查询学生:
	public Student findStudent(String id) throws Exception {
    
    
        if("".equals(id)){
    
    
            throw new Exception("id is null");
        }
        int len = myStudents.size();
        for(int i = 0;i < len;++i){
    
    
            Student s = myStudents.get(i);
            if(id.equals(s.getId())) {
    
    
                return s;
            }
        }
        return null;
    }

1.5、功能3:描述

完成数据库的多表归类,这里我设计的是按照成绩划分 A 、 B 、 C 三个档次,分别记为:
(90-100)—— 完美
(60-90) —— 合格
(0-60) —— 糟糕
其实实现上很简单,就是从外存文件上,把总的学生信息文件(也就是数据库的表),按照成绩划分的约定,分成三个子表即可!

这里有个点需要注意:

要避免在用户不合理操作下的处理,比如说用户多此指令要求按照成绩分表,切记不能够累积处理,否则分出来的表的内容会内存冗余,造成很多重复数据嗷!

1.6、功能3:实现(只展示核心代码)

filterByScore() 方法
	public void filterByScore(boolean book) throws IOException {
    
    
        int len = myStudents.size();
        for(int i = 0;i < len;++i){
    
    
            Student s = myStudents.get(i);
            if(null == s){
    
    
                continue;
            }
            if(book){
    
    
                insertStudent(s);
            }
            switch (s.getScore() / 30)
            {
    
    
                case 3:
                    addIntoLevelFiles('A', s);
                    break;
                case 2:
                    addIntoLevelFiles('B', s);
                    break;
                default:
                    addIntoLevelFiles('C', s);
            }
        }
    }
addIntoLevelFiles() 方法
	private void addIntoLevelFiles(char level, Student s) throws IOException {
    
    
        BufferedWriter bw = null;
        switch (level)
        {
    
    
            case 'A':
                bw = new BufferedWriter(
                        new OutputStreamWriter(
                                new FileOutputStream(new File("StudentOfFiles\\Score-perfect.txt"), true),
                                "UTF-8"
                        )
                );
                break;
            case 'B':
                bw = new BufferedWriter(
                        new OutputStreamWriter(
                                new FileOutputStream(new File("StudentOfFiles\\Score-pass.txt"), true),
                                "UTF-8"
                        )
                );
                break;
            default:
                bw = new BufferedWriter(
                        new OutputStreamWriter(
                                new FileOutputStream(new File("StudentOfFiles\\Score-bad.txt"), true),
                                "UTF-8"
                        )
                );
        }
        String strLine = new String(s.getName() + "\t" + s.getId() + "\t" + s.getAge() + "\t" + s.getScore());
        bw.write(strLine + "\t\n");
        bw.flush();
        bw.close();
    }

1.7、功能4:描述

完成学生排序,按照的排序约定是:
① 如若成绩不一致,则成绩降序排序
② 如若成绩一致,则按照姓名的字典序排序

这里有个点需要注意:

这里的排序我采用的是内排序,这个也是比较合理的,毕竟数据库的图形页面对用户而言只是一个映射,不必做外排序。

1.8、功能4:实现(只展示核心代码)

	public void sortStudentList(){
    
    
        Collections.sort(myStudents, new Comparator<Student>() {
    
    
            @Override
            public int compare(Student s1, Student s2) {
    
    
                if(s1.getScore() != s2.getScore()){
    
    
                    return s2.getScore() - s1.getScore();
                }
                else{
    
    
                    return s1.getName().compareTo(s2.getName());
                }
            }
        });
    }

1.9、功能5:描述

清空数据库的功能,这个很简单,只需要给每个文件的开头(FileInputStream 的第二个参数改成true)写入一个空字符串即可!

1.10、功能5:实现(只展示核心代码)

	public void exitDatabase(boolean book) throws IOException {
    
    
        BufferedWriter bw;
        if(book) {
    
    
            bw = new BufferedWriter(
                    new OutputStreamWriter(
                            new FileOutputStream(new File("StudentOfFiles\\StudentInfo.txt")),
                            "UTF-8"
                    )
            );
            bw.write("");
            bw.flush();
        }
        bw = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(new File("StudentOfFiles\\Score-perfect.txt")),
                        "UTF-8"
                )
        );
        bw.write("");
        bw.flush();
        bw = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(new File("StudentOfFiles\\Score-pass.txt")),
                        "UTF-8"
                )
        );
        bw.write("");
        bw.flush();
        bw = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(new File("StudentOfFiles\\Score-bad.txt")),
                        "UTF-8"
                )
        );
        bw.write("");
        bw.flush();
        bw.close();
    }

二、系统设计

本系统我按照MVC设计模式进行设计,设计如下:

Models :

设计了 Student 类,相当于给数据库建表

Views:

设计了 Main 类,给用户提供了人机交互性相对较号的交互界面

Controller:

设计了 StudentDatabaseOperate 类,完成了所有从 Models(数据库) 到 Views 的所有功能的实现,在 Views 里面仅仅是对功能进行了 二次 封装和调用。

三、文件结构:

在这里插入图片描述
这个文件结构如上,一会方便大家调试和复盘。

四、完整项目代码

Models 层:

import java.util.Comparator;

/**
 * 功能:操作对象:学生类
 * @author jiangzl
 */
class Student {
    
    
    private String name, id;
    private int age, score;

    public Student(String name, String id, int age, int score){
    
    
        this.name = name;
        this.id = id;
        this.age = age;
        this.score = score;
    }

    public String getName(){
    
    
        return name;
    }

    public int getScore(){
    
    
        return score;
    }

    public String getId(){
    
    
        return id;
    }

    public int getAge(){
    
    
        return age;
    }

    @Override
    public String toString(){
    
    
        return new String("姓名:" + name + " 年龄:" + age + " 分数:" + score);
    }
}

Controller 层

import java.io.*;
import java.util.*;

/**
 * 功能:文本数据库操作类
 * @author jiangzl
 */
class StudentDatabaseOperate {
    
    
    private List<Student> myStudents;
    private File file;

    public StudentDatabaseOperate(String filename){
    
    
        this.file = new File(filename);
        this.myStudents = new ArrayList<>();
    }

    public void sortStudentList(){
    
    
        Collections.sort(myStudents, new Comparator<Student>() {
    
    
            @Override
            public int compare(Student s1, Student s2) {
    
    
                if(s1.getScore() != s2.getScore()){
    
    
                    return s2.getScore() - s1.getScore();
                }
                else{
    
    
                    return s1.getName().compareTo(s2.getName());
                }
            }
        });
    }

    public Student findStudent(String id) throws Exception {
    
    
        if("".equals(id)){
    
    
            throw new Exception("id is null");
        }
        int len = myStudents.size();
        for(int i = 0;i < len;++i){
    
    
            Student s = myStudents.get(i);
            if(id.equals(s.getId())) {
    
    
                return s;
            }
        }
        return null;
    }

    public int getSize(){
    
    
        return myStudents.size();
    }

    public List<Student> getMyStudents(){
    
    
        return myStudents;
    }

    public void insertStudent(Student s) throws IOException {
    
    
        myStudents.add(s);
        BufferedWriter bw = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(file, true),
                        "UTF-8"
                )
        );
        String strLine = new String(s.getName() + "\t" + s.getId() + "\t" + s.getAge() + "\t" + s.getScore());
        bw.write(strLine + "\t\n");
        bw.flush();
        bw.close();
    }

    private void addIntoLevelFiles(char level, Student s) throws IOException {
    
    
        BufferedWriter bw = null;
        switch (level)
        {
    
    
            case 'A':
                bw = new BufferedWriter(
                        new OutputStreamWriter(
                                new FileOutputStream(new File("StudentOfFiles\\Score-perfect.txt"), true),
                                "UTF-8"
                        )
                );
                break;
            case 'B':
                bw = new BufferedWriter(
                        new OutputStreamWriter(
                                new FileOutputStream(new File("StudentOfFiles\\Score-pass.txt"), true),
                                "UTF-8"
                        )
                );
                break;
            default:
                bw = new BufferedWriter(
                        new OutputStreamWriter(
                                new FileOutputStream(new File("StudentOfFiles\\Score-bad.txt"), true),
                                "UTF-8"
                        )
                );
        }
        String strLine = new String(s.getName() + "\t" + s.getId() + "\t" + s.getAge() + "\t" + s.getScore());
        bw.write(strLine + "\t\n");
        bw.flush();
        bw.close();
    }

    public void filterByScore(boolean book) throws IOException {
    
    
        int len = myStudents.size();
        for(int i = 0;i < len;++i){
    
    
            Student s = myStudents.get(i);
            if(null == s){
    
    
                continue;
            }
            if(book){
    
    
                insertStudent(s);
            }
            switch (s.getScore() / 30)
            {
    
    
                case 3:
                    addIntoLevelFiles('A', s);
                    break;
                case 2:
                    addIntoLevelFiles('B', s);
                    break;
                default:
                    addIntoLevelFiles('C', s);
            }
        }
    }

    public void exitDatabase(boolean book) throws IOException {
    
    
        BufferedWriter bw;
        if(book) {
    
    
            bw = new BufferedWriter(
                    new OutputStreamWriter(
                            new FileOutputStream(new File("StudentOfFiles\\StudentInfo.txt")),
                            "UTF-8"
                    )
            );
            bw.write("");
            bw.flush();
        }
        bw = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(new File("StudentOfFiles\\Score-perfect.txt")),
                        "UTF-8"
                )
        );
        bw.write("");
        bw.flush();
        bw = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(new File("StudentOfFiles\\Score-pass.txt")),
                        "UTF-8"
                )
        );
        bw.write("");
        bw.flush();
        bw = new BufferedWriter(
                new OutputStreamWriter(
                        new FileOutputStream(new File("StudentOfFiles\\Score-bad.txt")),
                        "UTF-8"
                )
        );
        bw.write("");
        bw.flush();
        bw.close();
    }

    public void getDataFromFileToMem() throws Exception {
    
    
        BufferedReader br = new BufferedReader(
                new InputStreamReader(
                        new FileInputStream(new File("StudentOfFiles\\StudentInfo.txt")),
                        "UTF-8"
                )
        );
        String strLine = null;
        while((strLine = br.readLine()) != null){
    
    
            strLine = strLine.replaceAll(" {2,}", " ");
            String[] splitArray = strLine.split("\\ |\\t");
            if(splitArray.length != 4){
    
    
                throw new Exception("读取信息有误!");
            }
            else{
    
    
                myStudents.add(new Student(splitArray[0], splitArray[1],
                        Integer.parseInt(splitArray[2]), Integer.parseInt(splitArray[3])));
            }
        }
        br.close();
    }
}

Views 层

import java.io.*;
import java.util.Scanner;

/**
 * 功能:测试类
 * @author 江政良
 */
public class Main {
    
    

    private static void cmdOfInsert(StudentDatabaseOperate sdo, Scanner sc){
    
    
        System.out.println("----------------请问您一次需要插入多少名同学:----------------");
        int num = sc.nextInt();
        System.out.println("----------------请依次输入:姓名、学号、年龄、分数----------------");
        for(int i = 0;i < num;++i){
    
    
            String name = sc.next();
            String id = sc.next();
            int age = sc.nextInt();
            int score = sc.nextInt();
            Student s = new Student(name, id, age, score);
            try {
    
    
                sdo.insertStudent(s);
            }
            catch (Exception inertE){
    
    
                System.out.println("存在输入异常的同学!!");
            }
        }
    }

    private static void cmdOfFind(StudentDatabaseOperate sdo, Scanner sc){
    
    
        System.out.println("----------------请输入需要查找的同学的学号:----------------");
        Student ret = null;
        while(true) {
    
    
            String id = sc.nextLine();
            if("".equals(id)){
    
    
                continue;
            }
            try {
    
    
                ret = sdo.findStudent(id);
                break;
            } catch (Exception findE) {
    
    
                System.out.println("查找失败,重新输入id,检查id格式!");
            }
        }
        if(null != ret){
    
    
            System.out.println(ret);
        }
        else{
    
    
            System.out.println("查找到的学生不存在!");
        }
    }

    private static void cmdOfStudentSort(StudentDatabaseOperate sdo){
    
    
        sdo.sortStudentList();
        int len = sdo.getMyStudents().size();
        for(int i = 0;i < len;++i){
    
    
            System.out.println(sdo.getMyStudents().get(i));
        }
    }

    private static void cmdOfFilterToFile(StudentDatabaseOperate sdo){
    
    
        try {
    
    
            sdo.exitDatabase(false);
            sdo.filterByScore(false);
        }
        catch (Exception fileE){
    
    
            System.out.println("文件操作有误!");
        }
    }

    private static void cmdOfRemoveStudent(StudentDatabaseOperate sdo, Scanner sc){
    
    
        System.out.println("----------------请输入您要删除的学生的学号:----------------");
        String id = "";
        while(true) {
    
    
            id = sc.next();
            if(!"".equals(id)){
    
    
                break;
            }
        }
        int len = sdo.getSize(), pos = -1;
        for(int i = 0;i < len;++i){
    
    
            if(id.equals(sdo.getMyStudents().get(i).getId())){
    
    
                pos = i;
                break;
            }
        }
        try {
    
    
            if(-1 != pos){
    
    
                sdo.getMyStudents().remove(pos);
            }
            else{
    
    
                throw new IOException("error");
            }
            exit(sdo, true);
            sdo.filterByScore(true);
        } catch (IOException e) {
    
    
            System.out.println("文件内容删除有误!");
        }
    }

    private static void exit(StudentDatabaseOperate sdo, boolean book){
    
    
        try {
    
    
            sdo.exitDatabase(book);
        }
        catch (Exception exitE) {
    
    
            System.out.println("关闭系统错误!");
        }
    }

    private static void cmdOfResumeDataFromFile(StudentDatabaseOperate sdo){
    
    
        try {
    
    
            sdo.getDataFromFileToMem();
        } catch (Exception getDataE) {
    
    
            System.out.println("从数据库恢复数据到内存失败");
            System.exit(0);
        }
    }

    public static void main(String[] args){
    
    
        System.out.println("----------------欢迎使用学生管理后台----------------");
        String src = "StudentOfFiles\\StudentInfo.txt";
        StudentDatabaseOperate sdo = new StudentDatabaseOperate(src);
        cmdOfResumeDataFromFile(sdo);
        System.out.println("----------------请根据如下提示进行操作----------------");
        System.out.println("----------------输入0:清空数据库----------------");
        System.out.println("----------------输入1:加入学生----------------");
        System.out.println("----------------输入2:查找学生----------------");
        System.out.println("----------------输入3:学生等第排序----------------");
        System.out.println("----------------输入4:学生按成绩分类到文件----------------");
        System.out.println("----------------输入5:按照学号删除某同学的记录----------------");
        System.out.println("----------------输入“结束”:结束本系统----------------");
        Scanner sc = new Scanner(System.in);
        while(true) {
    
    
            int cmd = -1;
            String cmdStr = sc.next();
            if("结束".equals(cmdStr)){
    
    
                break;
            }
            try {
    
    
                cmd = Integer.parseInt(cmdStr);
            }
            catch (Exception cmdE){
    
    
                System.out.println("亲,这边不晓得你说什么哦,请重新输入!");
                continue;
            }
            switch (cmd) {
    
    
                case 0:
                    exit(sdo, true);
                    sdo.getMyStudents().clear();
                    break;
                case 1:
                    cmdOfInsert(sdo, sc);
                    break;
                case 2:
                    cmdOfFind(sdo, sc);
                    break;
                case 3:
                    cmdOfStudentSort(sdo);
                    break;
                case 4:
                    cmdOfFilterToFile(sdo);
                    break;
                case 5:
                    cmdOfRemoveStudent(sdo, sc);
                    break;
                default:
                    System.out.println("输入失败,请重新输入");
            }
            System.out.println("----------------请根据如下提示进行操作----------------");
            System.out.println("----------------输入0:清空数据库----------------");
            System.out.println("----------------输入1:加入学生----------------");
            System.out.println("----------------输入2:查找学生----------------");
            System.out.println("----------------输入3:学生等第排序----------------");
            System.out.println("----------------输入4:学生按成绩分类到文件----------------");
            System.out.println("----------------输入5:按照学号删除某同学的记录----------------");
            System.out.println("----------------输入“结束”:结束本系统----------------");
        }
        sc.close();
    }
}

五、写在后面的话

由于本人能力有限,写的、设计的不合理的地方还请各位提出!有好的建议或者意见也最好能够留言、私信给我,谢谢~~

对了,这里是我的GitHub上,关于这个项目的地址,欢迎多多Star!谢谢!

JavaSE版本的学生管理系统

猜你喜欢

转载自blog.csdn.net/qq_44274276/article/details/107811189