學(xué)生信息管理小系統(tǒng)(以XML為存儲方式)

為了更好地應(yīng)用XML,就寫了這個小項目。


下面是我的項目的目錄結(jié)構(gòu)


項目目錄

項目思路

  • dao是Date Access Object 數(shù)據(jù)訪問層,主要是負(fù)責(zé)操作數(shù)據(jù)
  • domain是實體層,類似于bean層,放置項目用到的實體Student
  • utils層是有關(guān)于XML操作的部分(一般實際開發(fā)中是數(shù)據(jù)庫操作部分)
  • view層是視圖層(實際開發(fā)中是GUI層,與用戶直接打交道)
  • Student.xml在這里相當(dāng)于我們的一個小小的數(shù)據(jù)庫

dao層設(shè)計


按照習(xí)慣的命名規(guī)則,我命名為StudentDao.java,具體實現(xiàn)的功能有添加學(xué)生信息,查找學(xué)生信息,刪除學(xué)生信息。這里僅僅是直接對數(shù)據(jù)操作的模塊,而把底層的操作XML文檔的放到了utils中。這也在一定程度上實現(xiàn)了分層的思想,雖然這并不明顯,也并不必需!

package dao;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import utils.XMLUtils;
import domain.Student;

public class StudentDao {

    
    /**
     * 添加學(xué)生信息模塊
     * @param student
     */
    public void add(Student student) {

        try {
            Document document = XMLUtils.getDocument();
            Element student_node = document.createElement("student");
            student_node.setAttribute("examid", student.getExamid());
            student_node.setAttribute("idcard", student.getIdcard());
            Element name = document.createElement("name");
            name.setTextContent(student.getName());

            Element location = document.createElement("location");
            location.setTextContent(student.getLocation());

            Element grade = document.createElement("grade");
            // 這里是一個類型轉(zhuǎn)換的隱藏之處。不太明顯但是卻十分的重要
            grade.setTextContent(student.getGrade() + "");

            // 將新生成的三個子節(jié)點插入到student標(biāo)簽內(nèi)
            student_node.appendChild(name);
            student_node.appendChild(location);
            student_node.appendChild(grade);

            // 對總的xml文檔中添加一個學(xué)生信息
            document.getElementsByTagName("exam").item(0)
                    .appendChild(student_node);
            //將內(nèi)存中的操作對象寫回到xml文件,真正實現(xiàn)對文件的操作
            XMLUtils.write2Xml(document);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            throw new RuntimeException(e);
        }

    }

    public void delete(String name) {

        try {
            Document document = XMLUtils.getDocument();
            NodeList name_node_list = document.getElementsByTagName("name");

            for (int i = 0; i < name_node_list.getLength(); i++) {
                if (name_node_list.item(i).getTextContent().equals(name)) {
                    Element person_node = (Element) name_node_list.item(i)
                            .getParentNode();
                    Element exam_node = (Element) person_node.getParentNode();
                    exam_node.removeChild(person_node);
                    //不要忘記將操作過的數(shù)據(jù)寫回,否則原信息是不會發(fā)生變化的
                    XMLUtils.write2Xml(document);
                    System.out.println("恭喜,學(xué)生信息刪除成功!");
                }
            }
        } catch (Exception e) {
            System.out.println("對不起,刪除操作未成功完成!請重試!");
            throw new RuntimeException(e);
        }

    }

    /**
     * 給定學(xué)生的考號查找該同學(xué)的詳細(xì)的信息(不用姓名的原因是姓名具有不唯一性)
     * @param examid
     * @return
     */
    public Student find(String examid) {
        Student student=null;
        try {
            Document document = XMLUtils.getDocument();
            NodeList examid_node_list = document.getElementsByTagName("student");
            
            //查找準(zhǔn)考證號與查找值相一致的學(xué)生節(jié)點
            for(int i=0; i<examid_node_list.getLength();i++){
                Element examid_element = (Element) examid_node_list.item(i);
                if(examid_element.getAttribute("examid").equals(examid.toString().trim())){
                    //采用非遞歸的方式獲取student的詳細(xì)信息
                    student = getStudentInfo(examid_element);
                    return student;
                }else{
                    continue;
                }
            }
            
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("對不起,未能正確的找到您要查找的學(xué)生的姓名!請確認(rèn)后重新嘗試!");
        }
        return student;
    }
    
    /**
     * 給定一個節(jié)點,采用非遞歸的方式遍歷該學(xué)生節(jié)點的詳細(xì)的信息
     * 缺點:不能很好地復(fù)用代碼,代碼維護性較差
     */
    public Student getStudentInfo(Element node){
        Student student = new Student();
        if(node!=null){
            String examid = node.getAttribute("examid");
            String idcard = node.getAttribute("idcard");
            NodeList node_list = node.getChildNodes();
            
            //由于collection 的不確定性,是隨機取出的數(shù)據(jù),導(dǎo)致bean中的數(shù)據(jù)不太對應(yīng)
            Node node_name = node_list.item(1);
            String name = node_name.getTextContent();
            Node node_location = node_list.item(2);
            String location = node_location.getTextContent();
            Node node_grade = node_list.item(0);
            String grade = node_grade.getTextContent()+"0.0";
            
            //將獲取的信息保存到bean中,并作為返回值返回!
            student.setExamid(examid);
            student.setGrade(Double.parseDouble(grade));
            student.setIdcard(idcard);
            student.setLocation(location);
            student.setName(name);
            return student;
        }
        System.out.println("this find operation is false!");
        return null;
    }

}


domain--實體層(bean)


package domain;

public class Student {

//注意將Student具有的屬性設(shè)置為私有的成員,然后設(shè)置getter,setter來訪問
    private String idcard;
    private String examid;
    private String name;
    private String location;
    private double grade;
    public String getIdcard() {
        return idcard;
    }
    public void setIdcard(String idcard) {
        this.idcard = idcard;
    }
    public String getExamid() {
        return examid;
    }
    public void setExamid(String examid) {
        this.examid = examid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getLocation() {
        return location;
    }
    public void setLocation(String location) {
        this.location = location;
    }
    public double getGrade() {
        return grade;
    }
    public void setGrade(double grade) {
        this.grade = grade;
    }
}


Utils層充當(dāng)工具,關(guān)聯(lián)底層操作


package utils;

import java.io.File;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;

public class XMLUtils {
    
    //all the utils methods are static 
    public static Document getDocument() throws Exception{
        
        DocumentBuilderFactory factory=DocumentBuilderFactory.newInstance();
        DocumentBuilder builder = factory.newDocumentBuilder();
        Document document = builder.parse(new File("src/Student.xml"));
        return document;
    }
    
    
    public static void write2Xml(Document document) throws Exception{
        
        TransformerFactory factory = TransformerFactory.newInstance();
        Transformer transformer=factory.newTransformer();
        
        //wrapper the two arguments
        DOMSource xmlSource = new DOMSource(document);
        
        StreamResult targetResult = new StreamResult(new File("src/Student.xml"));
        
        transformer.transform(xmlSource, targetResult);
        
}

}

小感悟:一般來說工具類的方法會做成靜態(tài)的私有的,這樣可以免去創(chuàng)建對象,又能很好的使用到它!


view層(與用戶直接交互的模塊)


這里僅僅是簡單的一些有好的交互,并沒有什么復(fù)雜的地方

package view;

import java.io.BufferedReader;
import java.io.InputStreamReader;

import dao.StudentDao;
import domain.Student;

public class Main {
    
    public static void main(String []args) throws Exception{
        System.out.println("添加學(xué)生(a),查找學(xué)生(f),刪除學(xué)生(d)");
        System.out.println("請輸入操作類型:");
        
        BufferedReader reader=new BufferedReader(new InputStreamReader(System.in));
        String type = reader.readLine();
        
        if(type.equalsIgnoreCase("a")){
            //add student
            //name examid idcard location grade
            try{
                System.out.println("請輸入學(xué)生姓名: ");
                String name = reader.readLine();
                
                System.out.println("請輸入學(xué)生準(zhǔn)考證號: ");
                String examid = reader.readLine();
                
                System.out.println("請輸入學(xué)生身份證號: ");
                String idcard = reader.readLine();
                
                System.out.println("請輸入學(xué)生所在地: ");
                String location = reader.readLine();
                
                System.out.println("請輸入學(xué)生成績: ");
                String grade = reader.readLine();
                
                Student student = new Student();
                student.setExamid(examid);
                student.setIdcard(idcard);
                student.setLocation(location);
                student.setName(name);
                student.setGrade(Double.parseDouble(grade));
                
                StudentDao studentDao = new StudentDao();
                studentDao.add(student);
                
                System.out.println("恭喜:學(xué)生信息添加成功!");
            }catch(Exception e){
                e.printStackTrace();
                System.out.println("對不起,學(xué)生信息數(shù)據(jù)添加失?。?);
            }
            
        }else if(type.equalsIgnoreCase("f")){
            //find student
            System.out.println("請輸入學(xué)生的準(zhǔn)考證號");
            StudentDao studentDao = new StudentDao();
            String examid = reader.readLine();
            Student student = studentDao.find(examid);
            PrintStudentInfo(student);
            
        }else if(type.equalsIgnoreCase("d")){
            //delete student
            System.out.println("請輸入學(xué)生的姓名");
            StudentDao studentDao = new StudentDao();
            String name = reader.readLine();
            studentDao.delete(name);
            
        }else{
            System.out.println("Not Support!");
        }
    }

    private static void PrintStudentInfo(Student student) {
        // TODO Auto-generated method stub
        if(student!=null){
            System.out.println("學(xué)生考號: \t"+student.getExamid());
            System.out.println("學(xué)生姓名: \t"+student.getName());
            System.out.println("學(xué)生身份證號碼 : \t"+student.getIdcard());
            System.out.println("學(xué)生所在地: \t"+student.getLocation());
            System.out.println("學(xué)生成績: \t"+student.getGrade());
        }
    }

}


處理素材和結(jié)果


Student.xml文件示意如下:

<?xml version="1.0" encoding="UTF-8" standalone="no"?><exam>
    <student examid="222" idcard="111">
        <name>Spring</name>
        <location>DaLian</location>
        <grade>89</grade>
    </student>

    <student examid="444" idcard="333">
        <name>Summer</name>
        <location>ShangHai</location>
        <grade>97</grade>
    </student>

    <student examid="201492115" idcard="410728">
        <name>郭璞</name>
        <location>大連</location>
        <grade>89.0</grade>
    </student>
    <student examid="123" idcard="1234567">
        <name>未命名</name>
        <location>不知道</location>
        <grade>0.0</grade>
    </student>
    
</exam>

操作結(jié)果:
添加學(xué)生操作


添加學(xué)生操作

添加學(xué)生信息結(jié)果


添加學(xué)生信息結(jié)果

刪除學(xué)生操作
刪除學(xué)生操作

刪除學(xué)生結(jié)果
刪除學(xué)生結(jié)果

查找學(xué)生詳細(xì)信息


查找學(xué)生詳細(xì)信息

總結(jié):


優(yōu)點:

  • 使用了分層思想(雖然有些地方并不是很明顯)

  • 模塊化的操作時的代碼邏輯更加的清晰

  • 較好的實現(xiàn)了對xml文件的CRUD操作

  • 結(jié)合了具體的項目,運用到了相關(guān)的知識點
    缺點:

  • 代碼處理上仍舊有很大的重復(fù)性

  • 設(shè)計模式的運用不是很明顯

  • 界面有點糟糕

有待改進之處:

  • 使用GUI,rich用戶體驗
  • 底層處理邏輯應(yīng)更加的精簡
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,775評論 18 399
  • 一. Java基礎(chǔ)部分.................................................
    wy_sure閱讀 4,017評論 0 11
  • 來源與:阿里云棲 禁止用于商業(yè)用途 ps:如果需要電子書 評論你們郵箱 我會發(fā)給你們 下面感覺還是有點亂 目錄 一...
    小向資源網(wǎng)閱讀 7,841評論 0 12
  • 激發(fā)客戶興趣 開場勿開門見山 (1)自我介紹: 姓名(適當(dāng)演繹,讓客戶容易記錄) 來自哪里公司,職位,資歷 你和客...
    K12增長狗閱讀 578評論 0 1
  • 楊緣夢閱讀 272評論 0 2

友情鏈接更多精彩內(nèi)容