面試常見問題——數據庫(一)

面試常見問題——數據庫(一)

目錄:

  1. 應用實例
    1. XML轉txt
    2. 建表
    3. 圖形化界面上傳文件,數據入庫
    4. 條件查詢,結果排序

一、應用實例

1、題目描述:a)讀入XML文本,按成績降序排序輸出成txt,如果成績相等,則按照姓名升序。(40分)
b)建三個表:課程表(課程Id,課程名稱),學生表(學生Id,學生姓名,性別),成績表(課程Id,學生Id,成績Id,分數)(20分)
c)編寫應用程序,要求有可視化界面,能進行數據庫連接,和實現如下操作:
①實現將xml文件導入數據庫。注意題目說不是直接導入,而是要寫代碼實現導入。(20分)
②實現數據表查看,同時可根據課程名查看學生的成績,成績要求從大到小排序(20分)

(1)前言:

  • 假設上機環境中沒有maven等構建工具,使用JDK版本爲1.8。數據庫考綱爲關係型數據庫,因此這裏用SQL Server2012進行測試。
  • 思路:
    • JTabbedPane設置三個選項卡:
      • 第一個選項卡,實現數據庫導入功能:用戶上傳XML文件,系統統一存放該xml文件到指定目錄下:C:/Users/鄧小藝/Desktop/2020考研複試/,在程序後臺中創建表(詳見ExamService類中createAllTable方法),文件上傳成功後,後臺將XML文件中數據解析成Java Bean,然後存放到數據庫中
      • 第二個選項卡,實現數據庫表查看功能:通過JPanel中存放JComboBox進行選擇不同數據表查看其內容,內容展示由JTable + JScrollPane + AbstractTableModel實現(詳見ViewAllDataPanel類)
      • 第三個選項卡,實現按照課程名查看學生成績的功能:通過JPanel中存放JComboBox,選項卡中課程名添加監聽器實時更新,內容展示由JTable + JScrollPane + AbstractTableModel實現(詳見GetGradePanel類)

(2)遇到的問題及解決方案:

  • 問題1:打包後出現錯誤:java.lang.SecurityException: Invalid signature file digest for Manifest main attributes
  • 解決方案:
    • 刪除打包後jar包中的*.SF,*.DSA,*.RSA文件
    • 在cmd中cd進入到jar包存放的目錄後,執行java -jar secondRoundExam.jar
    • 或者可以直接使用exe4j工具,將jar包轉換爲exe可執行程序
  • 問題2:JDK版本衝突:A JNI error has occurred, please check your installation and try again
  • 解決方案:
    • 多JDK版本可共存。打開環境變量,修改系統變量(比如我本機中java -version查看爲1.10,javac -version查看爲1.8,將其統一使用JDK1.8):
      • 創建環境變量:
        • JAVA8_HOME=C:\Program Files\Java\jdk1.8.0
        • JAVA10_HOME=C:\Program Files\Java\jdk-10.0.1
        • JAVA_HOME=%JAVA8_HOME%
      • 然後在path環境變量中添加%JAVA_HOME%\bin;%MAVEN_HOME%\bin;%JAVA_HOME%\jre\bin;其中該變量要放在C:\Program Files (x86)\Common Files\Oracle\Java\javapath;前面(如果存在)。
  • 問題3:使用idea打包流程出錯
  • 解決方案:
    • File -> Project Structure -> Artifacts -> 選擇Add JAR -> 選擇From modules with dependencies -> 指定Main Class ->  選擇extract to the target jar -> Directory for META-INF/MANIFEST.MF中修改路徑,去掉\main\java,修改後爲:D:\workspace\secondRoundExam\src -> 點擊OK即可。
  • 問題4:idea工程打開時默認jdk1.5
  • 解決方案:
    • 對工程統一使用JDK1.8。
      • File -> File Settings -> Build,Execution,Deployment -> Java Compiler -> Project bytecode version修改爲1.8,同時Target bytecode version修改爲1.8
      • File -> Project Structure -> Project -> Project SDK選擇1.8,下面Project language level選擇爲8
      • File -> Project Structure -> Modules -> Sources -> Language level選擇爲8
  • 問題5:配置SQL Server2012使用用戶名及密碼通過jdbc + TCP/IP連接
  • 解決方案:
    • SQL Server Management Studio配置:
      • 連接、選擇數據庫引擎,通過Windows身份驗證登錄後,右鍵選擇服務器屬性 -> 安全性 -> 服務器身份驗證選擇SQL Server和Windows身份驗證模式
      • 左側菜單欄 選擇安全性 -> 登錄名 -> 選擇sa右鍵屬性,設置密碼123456
    • 本地防火牆配置:
      • 打開控制面板 -> 系統和安全 -> Windows防火牆 -> 關閉防火牆
    • jdbc配置:
      • 提前準備好sqljdbc4.jar
      • 配置參數:
        • private static final String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
        • private static final String user = "sa";
        • private static final String password = "123456";
        • private static final String url = "jdbc:sqlserver://127.0.0.1:1433;DatabaseName=SCUT";

(3)程序界面實現以及包目錄截圖:

i)可視化界面:

ii)按成績降序輸出txt:

iii)Java工程目錄結構:


(4)測試樣例XML文件內容:

<grades>
    <grade grade_id="grade_001">
        <id>2019001</id>
        <name>張三</name>
        <course>計算機組成原理</course>
        <score>85</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_002">
        <id>2019002</id>
        <name>李四</name>
        <course>操作系統</course>
        <score>90</score>
        <sex>女</sex>
    </grade>
    <grade grade_id="grade_003">
        <id>2019003</id>
        <name>王五</name>
        <course>數據結構</course>
        <score>95</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_004">
        <id>2019004</id>
        <name>趙六</name>
        <course>計算機網絡</course>
        <score>70</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_005">
        <id>2019005</id>
        <name>鄭成</name>
        <course>數據庫</course>
        <score>90</score>
        <sex>女</sex>
    </grade>
    <grade grade_id="grade_006">
        <id>2019006</id>
        <name>劉奇</name>
        <course>編譯原理</course>
        <score>90</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_888">
        <id>2019007</id>
        <name>易烊千璽</name>
        <course>泥塑</course>
        <score>100</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_666">
        <id>2019008</id>
        <name>千璽零</name>
        <course>跳舞</course>
        <score>100</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_999">
        <id>2019009</id>
        <name>千璽一</name>
        <course>數據庫</course>
        <score>99</score>
        <sex>女</sex>
    </grade>
    <grade grade_id="grade_667">
        <id>2019010</id>
        <name>千璽二</name>
        <course>跳舞</course>
        <score>95</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_668">
        <id>2019011</id>
        <name>千璽三</name>
        <course>跳舞</course>
        <score>96</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_669">
        <id>2019012</id>
        <name>千璽3</name>
        <course>跳舞</course>
        <score>92.5</score>
        <sex>男</sex>
    </grade>

    <grade grade_id="grade_610">
        <id>2019013</id>
        <name>千璽四</name>
        <course>跳舞</course>
        <score>90.5</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_611">
        <id>2019014</id>
        <name>千璽五</name>
        <course>跳舞</course>
        <score>99</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_612">
        <id>2019015</id>
        <name>千璽六</name>
        <course>跳舞</course>
        <score>97.5</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_613">
        <id>2019016</id>
        <name>千璽七</name>
        <course>跳舞</course>
        <score>97.5</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_614">
        <id>2019008</id>
        <name>劉豔芬</name>
        <course>跳舞</course>
        <score>100</score>
        <sex>女</sex>
    </grade>
    <grade grade_id="grade_615">
        <id>2019018</id>
        <name>千璽八</name>
        <course>跳舞</course>
        <score>99</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_616">
        <id>2019019</id>
        <name>千璽九</name>
        <course>跳舞</course>
        <score>99</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_617">
        <id>2019020</id>
        <name>千璽十</name>
        <course>跳舞</course>
        <score>97.5</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_618">
        <id>2019021</id>
        <name>千璽十一</name>
        <course>跳舞</course>
        <score>97.5</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_619">
        <id>2019022</id>
        <name>千璽十二</name>
        <course>跳舞</course>
        <score>100</score>
        <sex>男</sex>
    </grade>
    <grade grade_id="grade_777">
        <id>2019008</id>
        <name>劉豔芬</name>
        <course>數據庫</course>
        <score>95</score>
        <sex>女</sex>
    </grade>
</grades>

(5)源程序代碼:

i)Util工具類:包括DB工具、XML解析工具、文件處理工具等

package com.remoa.test.util;

import com.remoa.test.domain.Course;
import com.remoa.test.domain.Grade;
import com.remoa.test.domain.Stu;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class DBUtil {
    private static final String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
    private static final String user = "sa";
    private static final String password = "123456";
    private static final String url = "jdbc:sqlserver://127.0.0.1:1433;DatabaseName=SCUT";
    public static final String TABLE_NOT_EXIST = "table-not-exist";

    public static Connection conn = null;

    public DBUtil(){
        try{
            Class.forName(driverName);

        }catch(Exception e){
            System.out.println("Connection Failed");
            e.printStackTrace();
        }
    }

    public static Connection getConnection(){
        try {
            conn = DriverManager.getConnection(url, user, password);
        }catch(Exception e){
            System.out.println("獲取連接失敗");
        }
        return conn;
    }

    public static void close(Statement stmt, ResultSet rst, Connection conn){
        try {
            if(stmt != null){
                stmt.close();
            }
            if(rst != null){
                rst.close();
            }
            if(conn != null) {
                conn.close();
            }
        } catch (SQLException e) {
            System.out.println("關閉連接失敗");
            e.printStackTrace();
        }
    }

    public static void initInsertAllTable(List<Grade> gradeList) {
        try {
            conn = getConnection();
            String deleteSql = "if exists(select * from sysobjects where name = 'grade' and type = 'U') " +
                    "delete from grade; " +
                    "if exists(select * from sysobjects where name = 'course' and type = 'U') " +
                    "delete from course; " +
                    "if exists(select * from sysobjects where name = 'stu' and type = 'U') " +
                    "delete from stu;";
            Statement stmt = conn.createStatement();
            stmt.execute(deleteSql);

            String courseSql = "if not exists(select * from course where course_name = ?) " +
                    "insert into course(course_name) values(?)";
            String stuSql = "if not exists(select * from stu where stu_id = ?) " +
                    "insert into stu values(?, ?, ?)";
            String gradeSql = "insert into grade values(?, ?, ?, ?)";

            PreparedStatement psCourse = conn.prepareStatement(courseSql);
            PreparedStatement psGrade = conn.prepareStatement(gradeSql);
            PreparedStatement psStu = conn.prepareStatement(stuSql);
            for(int i = 0; i < gradeList.size(); i++){
                psCourse.setString(1, gradeList.get(i).getCourse());
                psCourse.setString(2, gradeList.get(i).getCourse());
                psCourse.executeUpdate();
                ResultSet rst = stmt.executeQuery("select course_id from course where course_name = '" + 
                        gradeList.get(i).getCourse() + "'");
                rst.next();

                psStu.setString(1, gradeList.get(i).getStuId());//查看該學生信息是否已經插入了
                psStu.setString(2, gradeList.get(i).getStuId());
                psStu.setString(3, gradeList.get(i).getName());
                psStu.setString(4, gradeList.get(i).getSex());
                psStu.executeUpdate();

                psGrade.setInt(1, rst.getInt(1));
                psGrade.setString(2, gradeList.get(i).getStuId());
                psGrade.setString(3, gradeList.get(i).getGradeId());
                psGrade.setDouble(4, gradeList.get(i).getScore());
                psGrade.executeUpdate();
                close(null, rst, null);
            }
            close(psCourse, null, null);
            close(psGrade, null, null);
            close(psStu, null, conn);
            System.out.println("數據已成功導入數據庫");
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void createTable(String sql, String tableName){
        try {
            conn = getConnection();
            Statement stmt = conn.createStatement();
            stmt.executeUpdate(sql);
            close(stmt, null, conn);
            System.out.println("創建表" + tableName + "成功");
        } catch (Exception e) {
            System.out.println("創建表" + tableName + "失敗");
            e.printStackTrace();
        }
    }

    public static List<Grade> searchDataByCourse(String sql){
        List<Grade> resultList = new ArrayList<>();
        try {
            conn = getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rst = stmt.executeQuery(sql);
            while(rst.next()){
                if(rst.getString(1).equals(TABLE_NOT_EXIST)) {
                    break;
                }
                Grade grade = new Grade();
                grade.setCourseId(rst.getInt(1));
                grade.setStuId(rst.getString(2));
                grade.setGradeId(rst.getString(3));
                grade.setScore(rst.getDouble(4));
                grade.setCourse(rst.getString(5));
                grade.setName(rst.getString(6));
                resultList.add(grade);
            }
            close(stmt, rst, conn);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return resultList;
    }

    public static List<Stu> getAllStu(String sql){
        List<Stu> resultList = new ArrayList<>();
        try {
            conn = getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rst = stmt.executeQuery(sql);
            while(rst.next()){
                if(rst.getString(1).equals(TABLE_NOT_EXIST)) {
                    break;
                }
                Stu stu = new Stu();
                stu.setStuId(rst.getString(1));
                stu.setName(rst.getString(2));
                stu.setSex(rst.getString(3));
                resultList.add(stu);
            }
            close(stmt, rst, conn);
        } catch (SQLException e) {
            System.out.println("獲取學生表數據失敗");
            e.printStackTrace();
        }
        return resultList;
    }

    public static List<Course> getAllCourse(String sql){
        List<Course> resultList = new ArrayList<>();
        try {
            conn = getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rst = stmt.executeQuery(sql);
            while (rst.next()) {
                if(rst.getString(1).equals(TABLE_NOT_EXIST)) {
                    break;
                }
                Course course = new Course();
                course.setCourseId(rst.getInt(1));
                course.setCourse(rst.getString(2));
                resultList.add(course);
            }
            close(stmt, rst, conn);
            System.out.println("獲取課程表數據:" + resultList.size() + "條");
        } catch (SQLException e) {
            System.out.println("獲取課程表數據失敗");
            e.printStackTrace();
        }
        return resultList;
    }

    public static List<Grade> getAllGrade(String sql){
        List<Grade> resultList = new ArrayList<>();
        try {
            conn = getConnection();
            Statement stmt = conn.createStatement();
            ResultSet rst = stmt.executeQuery(sql);
            while(rst.next()){
                if(rst.getString(1).equals(TABLE_NOT_EXIST)) {
                    break;
                }
                Grade grade = new Grade();
                grade.setCourseId(rst.getInt(1));
                grade.setStuId(rst.getString(2));
                grade.setGradeId(rst.getString(3));
                grade.setScore(rst.getDouble(4));
                resultList.add(grade);
            }
            close(stmt, rst, conn);
        } catch (SQLException e) {
            System.out.println("獲取成績數據失敗");
            e.printStackTrace();
        }
        return resultList;
    }
}
package com.remoa.test.util;

import com.remoa.test.domain.Grade;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class XMLUtil {
    public static List<Grade> XMLRead(String path){
        List<Grade> resultList = new ArrayList<>();
        //初始化一個XML解析工廠
        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
        try {
            //創建解析器實例
            DocumentBuilder builder = factory.newDocumentBuilder();
            File file = null;
            if(path == null) {
                URL url = XMLUtil.class.getClassLoader().getResource("grades.xml");
                if(url != null) {
                    file = new File(url.getFile());
                }
            }else{
                file = new File(path);
            }
            Document document = builder.parse(file);
            //根據根元素名獲取根元素集合
            NodeList gradeList = document.getElementsByTagName("grade");
            for (int i = 0; i < gradeList.getLength(); i++) {
                Grade grade = new Grade();
                Element gradeElm = (Element) gradeList.item(i);
                //獲得屬性
                String gradeId = gradeElm.getAttribute("grade_id");
                grade.setGradeId(gradeId);
                //獲得子元素
                NodeList nodeList = gradeElm.getChildNodes();
                for (int j = 0; j < nodeList.getLength(); j++) {
                    Node node = nodeList.item(j);
                    if(node.getNodeType() == Node.ELEMENT_NODE){
                        Element child = (Element)node;
                        switch(child.getNodeName()){
                            case "id":
                                grade.setStuId(child.getTextContent());
                                break;
                            case "name":
                                grade.setName(child.getTextContent());
                                break;
                            case "course":
                                grade.setCourse(child.getTextContent());
                                break;
                            case "score":
                                grade.setScore(Double.valueOf(child.getTextContent()));
                                break;
                            case "sex":
                                grade.setSex(child.getTextContent());
                                break;
                        }
                    }
                }
                resultList.add(grade);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return resultList;
    }
}
package com.remoa.test.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStreamWriter;

public class FileUtil {
    public static void writeTxt(File file, String word){
        try {
            BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file, true)));
            out.write(word + "\r\n");
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

ii)圖形界面代碼:包括三個選項卡及主窗體

文件上傳以及數據庫導入:

package com.remoa.test.view;

import com.remoa.test.domain.Grade;
import com.remoa.test.service.ExamService;

import javax.swing.*;
import javax.swing.filechooser.FileFilter;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.*;
import java.util.List;
import java.util.UUID;

//導入XML文件到數據庫
public class UploadJPanel extends JPanel{
    ExamService service = new ExamService();
    public UploadJPanel(String directPath, String outputPath){
        JLabel label = new JLabel("1.上傳xml文件以導入數據庫:");
        label.setHorizontalAlignment(SwingConstants.LEFT);
        add(label);
        JToolBar toolBar = new JToolBar();
        JButton button = new JButton("上傳文件");
        button.setHorizontalAlignment(SwingConstants.CENTER);
        toolBar.add(button);
        add(toolBar);
        button.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                importFile(new JButton(), directPath, outputPath);
            }
        });
    }

    public void importFile(JButton button, String directPath, String outputPath){
        JFileChooser chooser = new JFileChooser();
        chooser.setMultiSelectionEnabled(false);
        chooser.setFileFilter(new FileFilter() {
            @Override
            public boolean accept(File f) {
                if(f.getName().endsWith(".txt") || f.getName().endsWith(".xml") || f.isDirectory()){
                    return true;
                }
                return false;
            }

            @Override
            public String getDescription() {
                return "請選擇txt或xml文件";
            }
        });
        chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
        int returnVal = chooser.showOpenDialog(button);
        try {
            if(returnVal == JFileChooser.APPROVE_OPTION) {
                File file = chooser.getSelectedFile();
                if (file.getName().endsWith(".txt") || file.getName().endsWith(".xml") ) {
                    InputStream inputStream;
                    OutputStream out;
                    String absolutePath = directPath + file.getName();
                    File tmp = new File(absolutePath);
                    if (tmp.exists()) {
                        absolutePath = directPath + UUID.randomUUID().toString().substring(0,9) + file.getName();
                    }
                    inputStream = new FileInputStream(file);
                    byte[] buffer = new byte[1024];
                    out = new FileOutputStream(absolutePath);
                    int len = 0;
                    while ((len = inputStream.read(buffer)) != -1) {
                        out.write(buffer, 0, len);
                    }
                    out.close();
                    inputStream.close();
                    List<Grade> gradeList = service.getXMLGrade(absolutePath);
                    service.insertAllData(gradeList);
                    //按照成績降序排序輸出成txt
                    service.writeTxt(gradeList, outputPath);
                    JOptionPane.showMessageDialog(null, "數據導入數據庫成功", "提示", JOptionPane.INFORMATION_MESSAGE);
                }else{
                    JOptionPane.showMessageDialog(null, "請按格式上傳", "提示", JOptionPane.WARNING_MESSAGE);
                }
            }
        } catch (Exception e) {
            System.out.println("文件上傳異常");
            JOptionPane.showMessageDialog(null, "上傳失敗", "提示", JOptionPane.ERROR_MESSAGE);
            e.printStackTrace();
        }
    }
}

查看所有庫表:

package com.remoa.test.view;

import com.remoa.test.domain.Course;
import com.remoa.test.domain.Grade;
import com.remoa.test.domain.Stu;
import com.remoa.test.service.ExamService;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.List;

public class ViewAllDataPanel extends JPanel {
    public ViewAllDataPanel(){
        ExamService service = new ExamService();
        JLabel label2 = new JLabel("2.查看所有數據庫表:");
        add(label2);
        JComboBox<String> comboBox = new JComboBox<>();
        String[] items = new String[]{"--請選擇--", "課程表", "學生表", "成績表"};
        DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>(items);
        comboBox.setModel(model);
        add(comboBox);
        comboBox.addItemListener(new ItemListener() {
            JScrollPane scrollPane = new JScrollPane();
            JTable table = null;
            @Override
            public void itemStateChanged(ItemEvent e) {
                System.out.println("click :" +e.getItem().toString());
                AbstractTableModel model = null;
                if(e.getItem().toString().equals("課程表")){
                    model = new CourseDataModel();
                }else if(e.getItem().toString().equals("學生表")){
                    model = new StuDataModel();
                }else if(e.getItem().toString().equals("成績表")){
                    model = new GradeDataModel();
                }
                if(model != null) {
                    model.fireTableDataChanged();
                    table = new JTable(model);
                    table.setPreferredSize(new Dimension(500, 800));
                }else{
                    table = null;
                }
                scrollPane.getViewport().add(table);
                add(scrollPane);
                revalidate();
            }
        });

    }
}

class CourseDataModel extends AbstractTableModel {
    List<Course> courseList;
    public CourseDataModel(){
        ExamService service = new ExamService();
        courseList = service.getAllCourse();
    }

    @Override
    public int getRowCount() {
        return courseList.size();
    }

    @Override
    public int getColumnCount() {
        return 2;
    }

    //數據庫查詢字段依次返回:course_id、course_name
    //將每一列賦予對應的list中的值
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Course course = courseList.get(rowIndex);
        switch(columnIndex){
            case 0:
                return course.getCourseId();
            case 1:
                return course.getCourse();
        }
        return null;
    }

    @Override
    public String getColumnName(int column){
        switch (column){
            case 0:
                return "課程Id";
            case 1:
                return "課程名稱";
        }
        return null;
    }
}

class StuDataModel extends AbstractTableModel {
    List<Stu> stuList;
    public StuDataModel(){
        ExamService service = new ExamService();
        stuList = service.getAllStu();
    }

    @Override
    public int getRowCount() {
        return stuList.size();
    }

    @Override
    public int getColumnCount() {
        return 3;
    }

    //數據庫查詢字段依次返回:stu_id、name、sex
    //將每一列賦予對應的list中的值
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Stu stu = stuList.get(rowIndex);
        switch(columnIndex){
            case 0:
                return stu.getStuId();
            case 1:
                return stu.getName();
            case 2:
                return stu.getSex();
        }
        return null;
    }

    @Override
    public String getColumnName(int column){
        switch (column){
            case 0:
                return "學生Id";
            case 1:
                return "學生姓名";
            case 2:
                return "性別";
        }
        return null;
    }
}


class GradeDataModel extends AbstractTableModel {
    List<Grade> gradeList;
    public GradeDataModel(){
        ExamService service = new ExamService();
        gradeList = service.getAllGrade();
    }

    @Override
    public int getRowCount() {
        return gradeList.size();
    }

    @Override
    public int getColumnCount() {
        return 4;
    }

    //數據庫查詢字段依次返回:course_id、stu_id、grade_id、score
    //將每一列賦予對應的list中的值
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Grade grade = gradeList.get(rowIndex);
        switch(columnIndex){
            case 0:
                return grade.getCourseId();
            case 1:
                return grade.getStuId();
            case 2:
                return grade.getGradeId();
            case 3:
                return grade.getScore();
        }
        return null;
    }

    @Override
    public String getColumnName(int column){
        switch (column){
            case 0:
                return "課程Id";
            case 1:
                return "學生Id";
            case 2:
                return "成績Id";
            case 3:
                return "分數";
        }
        return null;
    }
}

按照課程名查看成績:

package com.remoa.test.view;

import com.remoa.test.domain.Course;
import com.remoa.test.domain.Grade;
import com.remoa.test.service.ExamService;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;

import static java.util.Collections.sort;

public class GetGradePanel extends JPanel {
    public GetGradePanel(){
        ExamService service = new ExamService();
        JLabel label = new JLabel("3.課程名:");
        add(label);
        DefaultComboBoxModel<String> model = new DefaultComboBoxModel<>();
        model.addElement("------請選擇課程------");
        JComboBox comboBox = new JComboBox(model);
        add(comboBox);
        comboBox.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseEntered(MouseEvent e) {
                mouseClicked(e);
            }

            @Override
            public void mouseClicked(MouseEvent e) {
                int index = comboBox.getSelectedIndex();
                model.removeAllElements();
                model.addElement("------請選擇課程------");
                List<Course> list = service.getAllCourse();
                for (int i = 0; i < list.size(); i++) {
                    model.addElement(list.get(i).getCourse());
                }
                comboBox.setModel(model);
                if(index < list.size()) {
                    comboBox.setSelectedIndex(index);
                }
            }
        });
        comboBox.addItemListener(new ItemListener() {
            JScrollPane scrollPane = new JScrollPane();
            JTable table = null;
            @Override
            public void itemStateChanged(ItemEvent e) {
                if(table != null){
                    remove(table);
                }
                if(e.getStateChange() == ItemEvent.SELECTED){
                    AllDataModel model = new AllDataModel(e.getItem().toString());
                    model.fireTableDataChanged();//刷新表格以顯示數據
                    table = new JTable(model);
                    table.setPreferredSize(new Dimension(600, 800));
                    scrollPane.getViewport().add(table);
                    add(scrollPane);
                    revalidate();
                }
            }
        });
    }
}

class AllDataModel extends AbstractTableModel{
    List<Grade> gradeList;
    public AllDataModel(String name){
        ExamService service = new ExamService();
        gradeList = service.searchGrade(name);
        sort(gradeList);
    }

    @Override
    public int getRowCount() {
        return gradeList.size();
    }

    @Override
    public int getColumnCount() {
        return 6;
    }

    //數據庫查詢字段依次返回:course_id、stu_id、grade_id、score、course_name、stu_name
    //將每一列賦予對應的list中的值
    @Override
    public Object getValueAt(int rowIndex, int columnIndex) {
        Grade grade = gradeList.get(rowIndex);
        switch(columnIndex){
            case 0:
                return grade.getGradeId();
            case 1:
                return grade.getStuId();
            case 2:
                return grade.getName();
            case 3:
                return grade.getCourseId();
            case 4:
                return grade.getCourse();
            case 5:
                return grade.getScore();
        }
        return null;
    }

    @Override
    public String getColumnName(int column){
        switch (column){
            case 0:
                return "成績Id";
            case 1:
                return "學生Id";
            case 2:
                return "學生姓名";
            case 3:
                return "課程Id";
            case 4:
                return "課程名稱";
            case 5:
                return "分數";
        }
        return null;
    }
}

選項卡類:

package com.remoa.test.view;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;

public class MyTabbedPane extends JTabbedPane {
    public MyTabbedPane(String inputPath, String outputPath){
        addTab("數據庫導入", new UploadJPanel(inputPath, outputPath));
        addTab("數據庫表查看", new ViewAllDataPanel());
        addTab("根據課程名查成績", new GetGradePanel());
        setPreferredSize(new Dimension(600, 350));
        addChangeListener(new ChangeListener() {
            @Override
            public void stateChanged(ChangeEvent e) {
                System.out.println("change to:" + getTitleAt(getSelectedIndex()));
            }
        });
    }
}

主窗體類:

package com.remoa.test.view;

import javax.swing.*;
import java.awt.*;

public class MyView extends JFrame {
    public MyView(String inputPath, String outputPath){
        setLayout(new FlowLayout());
        setBounds(100, 100, 700, 400);
        setVisible(true);
        setTitle("複試 Remoa:3114005847");
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        add(new MyTabbedPane(inputPath, outputPath));
        validate();
    }
}

iii)實體類:學生實體、課程實體、成績實體

package com.remoa.test.domain;

public class Stu {
    private String stuId;
    private String name;
    private String sex;

    public String getStuId() {
        return stuId;
    }

    public void setStuId(String stuId) {
        this.stuId = stuId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }
}
package com.remoa.test.domain;

public class Course {
    private Integer courseId;
    private String course;

    public Integer getCourseId() {
        return courseId;
    }

    public void setCourseId(Integer courseId) {
        this.courseId = courseId;
    }

    public String getCourse() {
        return course;
    }

    public void setCourse(String course) {
        this.course = course;
    }
}
package com.remoa.test.domain;

public class Grade implements Comparable<Grade>{
    private String gradeId;
    private String stuId;
    private String name;
    private String course;
    private double score;
    private Integer courseId;

    public Integer getCourseId() {
        return courseId;
    }

    public void setCourseId(Integer courseId) {
        this.courseId = courseId;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    private String sex;

    public String getGradeId() {
        return gradeId;
    }

    public void setGradeId(String gradeId) {
        this.gradeId = gradeId;
    }

    public String getStuId() {
        return stuId;
    }

    public void setStuId(String stuId) {
        this.stuId = stuId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCourse() {
        return course;
    }

    public void setCourse(String course) {
        this.course = course;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }

    @Override
    public String toString() {
        return this.getGradeId() + "," + getStuId() + "," + getName() + "," + getCourse() + "," + getScore();
    }

    @Override
    public int compareTo(Grade grade) {
        if(grade.getScore() == this.getScore()){
            return this.getName().compareTo(grade.getName()); //得分相同,則按照姓名升序
        }
        return (int)(grade.getScore() - this.getScore());//按照成績得分降序
    }
}

iv)數據訪問dao層:StuDao、CourseDao、GradeDao

package com.remoa.test.dao;

import com.remoa.test.domain.Stu;
import com.remoa.test.util.DBUtil;

import java.util.List;

public class StuDao {
    public List<Stu> getAllStu(){
        String sql = "if exists(select * from sysobjects where name = 'stu' and type = 'U') " +
                "select * from stu else select '" + DBUtil.TABLE_NOT_EXIST + "'";
        return DBUtil.getAllStu(sql);
    }
}
package com.remoa.test.dao;

import com.remoa.test.domain.Course;
import com.remoa.test.util.DBUtil;

import java.util.List;

public class CourseDao {
    public List<Course> getAllCourse(){
        String sql = "if exists(select * from sysobjects where name = 'course' and type = 'U') " +
                "select * from course else select '" + DBUtil.TABLE_NOT_EXIST + "'";
        return DBUtil.getAllCourse(sql);
    }
}
package com.remoa.test.dao;

import com.remoa.test.domain.Grade;
import com.remoa.test.util.DBUtil;

import java.util.List;

public class GradeDao {
    public void createCourse() {
        String sql = "if not exists(select * from sysobjects where name = 'course' and type = 'U') " +
                "create table course(" +
                "course_id int primary key identity(1, 1)," + //從1開始,每次增長1
                "course_name varchar(50) not null" +
                ");";
        DBUtil.createTable(sql, "course");
    }

    public void createStu(){
        String sql = "if not exists(select * from sysobjects where name = 'stu' and type = 'U') " +
                "create table stu(" +
                "stu_id varchar(50) primary key," +
                "name varchar(50) not null," +
                "sex varchar(50) not null" +
                ");";
        DBUtil.createTable(sql, "stu");
    }

    public void createGrade(){
        String sql = "if not exists(select * from sysobjects where name = 'grade' and type = 'U') " +
                "create table grade(" +
                "course_id int, " +
                "stu_id varchar(50), " +
                "grade_id varchar(50) primary key," +
                "score decimal(4,1) not null," +
                "foreign key(course_id) references course(course_id)," +
                "foreign key(stu_id) references stu(stu_id)" +
                ");";
        DBUtil.createTable(sql, "grade");
    }

    public List<Grade> getGradeByCourse(String course){
        String sql = "if exists(select * from sysobjects where name = 'grade' and type = 'U') " +
                "select grade.*, course.course_name, stu.name from grade, course, stu " +
                "where course_name = '" + course + "' " +
                "and grade.course_id = course.course_id " +
                "and stu.stu_id = grade.stu_id " +
                "else select '" + DBUtil.TABLE_NOT_EXIST + "'";
        return DBUtil.searchDataByCourse(sql);
    }

    public List<Grade> getAllGrade(){
        String sql = "if exists(select * from sysobjects where name = 'grade' and type = 'U') " +
                "select * from grade else select '" + DBUtil.TABLE_NOT_EXIST + "'";
        return DBUtil.getAllGrade(sql);
    }
}

v)邏輯服務service層:

package com.remoa.test.service;

import com.remoa.test.dao.CourseDao;
import com.remoa.test.dao.GradeDao;
import com.remoa.test.dao.StuDao;
import com.remoa.test.domain.Course;
import com.remoa.test.domain.Grade;
import com.remoa.test.domain.Stu;
import com.remoa.test.util.DBUtil;
import com.remoa.test.util.FileUtil;
import com.remoa.test.util.XMLUtil;

import java.io.File;
import java.util.List;

import static java.util.Collections.sort;

public class ExamService {
    GradeDao gradeDao = new GradeDao();
    CourseDao courseDao = new CourseDao();
    StuDao stuDao = new StuDao();

    public void insertAllData(List<Grade> list){
        DBUtil.initInsertAllTable(list);
    }

    public void createAllTable(){
        gradeDao.createStu();
        gradeDao.createCourse();
        gradeDao.createGrade();
    }

    public List<Grade> searchGrade(String courseName){
        return gradeDao.getGradeByCourse(courseName);
    }

    public List<Course> getAllCourse(){
        return courseDao.getAllCourse();
    }

    public List<Grade> getAllGrade(){
        return gradeDao.getAllGrade();
    }

    public List<Stu> getAllStu(){
        return stuDao.getAllStu();
    }

    public List<Grade> getXMLGrade(String path){
        return XMLUtil.XMLRead(path);
    }

    public void writeTxt(List<Grade> list, String outputPath){
        sort(list);
        try {
            File file = new File(outputPath);
            if(file.exists()){
                file.delete();
            }
            file.createNewFile();
            for (int i = 0; i < list.size(); i++) {
                FileUtil.writeTxt(file, list.get(i).toString());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

vi)業務控制controller層:

package com.remoa.test.controller;

import com.remoa.test.view.MyView;
import com.remoa.test.service.ExamService;

public class Main {
    private static final String outputPath = "C:/Users/鄧小藝/Desktop/output.txt";
    private static final String uploadRootPath = "C:/Users/鄧小藝/Desktop/2020考研複試/";

    public static void main(String[] args) {
        ExamService service = new ExamService();
        /*1、建三個表:課程表(課程Id,課程名稱),
            學生表(學生Id,學生姓名,性別),
            成績表(課程Id,學生Id,成績Id,分數)
        */
        service.createAllTable();

        //方式1:直接在程序中後臺導入所有數據
        //service.insertAllData(service.getXMLGrade(uploadRootPath + "grades.xml"));

        //方式2:讓用戶在界面上操作導入xml文件數據到數據庫,同時按照成績降序排序輸出成txt
        new MyView(uploadRootPath, outputPath);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章