中南林业科技大学Java实验报告十二:数据库系统设计 - 从0到1搭建java可视化学生管理系统源代码

发布于:2022-11-09 ⋅ 阅读:(369) ⋅ 点赞:(0)

文章目录

实验12 数据库系统设计

12.1 实验目的

  1. 掌握MVC设计方法。
  2. 利用JDBC连接数据库,并对数据库进行操作。

12.2 实验内容

12.2.1 设计一个数据库Student,包含成绩表Score,其中属性包含学号,姓名,专业,班级,平均成绩。字段名和类型自行定义,但需合理。

12.2.1.1 创建数据库student

DROP DATABASE IF EXISTS student;
CREATE DATABASE student;

12.2.1.2 创建score表

USE student;
CREATE TABLE score(
	 stu_id INT PRIMARY KEY NOT NULL COMMENT '学号',
	`name` VARCHAR(16) NOT NULL COMMENT '姓名',
	 major VARCHAR(16) NOT NULL COMMENT '专业',
	 class_num TINYINT NOT NULL COMMENT '班级',
	 avg_score DECIMAL(5,2) COMMENT '平均成绩'
)COMMENT = '成绩表';

12.2.1.3 增加avg_score索引

-- 默认升序索引,但对单列降序同样生效
ALTER TABLE score
ADD INDEX idx_score(avg_score);

12.2.1.4 增加记录数据

INSERT INTO score(stu_id,`name`,major,class_num,avg_score) VALUES
(20217880,'小草','金融理财类',1,94),
(20217865,'夜莺','播音主持类',3,93),
(20217881,'雨浪','新闻传媒类',2,95),
(20217883,'谢添','计算机类',6,96),
(20217853,'狐狸半面添','计算机科学类',2,94),
(20217864,'忧愁剑客','剑术刀影类',1,95),
(20217882,'小思树','医药科学类',3,95.5),
(20217888,'小宋','生命科学类',7,94.2),
(20217889,'思熠','材料化学类',5,93.5),
(20217893,'浪语','哲学与马克思类',2,94.6),
(20217892,'艾浪','法学教育类',8,96.5),
(20217884,'浪音','科学生命类',4,97),
(20217886,'思浪','思想道德类',5,96.6),
(20217854,'逐浪者','海洋生命类',1,96.4);

-- 查看增加情况
SELECT * FROM score;

12.2.2 设计一个学生成绩管理界面

12.2.2.0 说明

1.实验要求
  • 利用Jtable组件和其对应的Model,将数据库Student中的数据读出并按照平均成绩降序排序。最终效果图:

    image-20221109103608803

  • 执行相应操作前应进行有效性检查,即数据库中是否有与学号相一致的主键,如果有则不能添加,并提示系统中已有该生数据,删除时则提示是否删除,点击确定删除。修改也做类似操作,在添加时必须保证所有选项不为空,删除的判断是仅需判断学号是否为空即可。

    image-20221109103634586

2.从0到1搭建学生成绩管理系统java整体结构

image-20221109110856918

3.最终实现功能

image-20221109124516711

  1. 本项目需要进行数据库连接,下载,安装与使用MySQL并下载图形化界面软件查看文章:MySQL下载与安装、mysql服务启动与停止、mysql使用cmd命令行登录、SQLyog下载与安装,sqlyog登录与操作mysql_是谢添啊的博客-CSDN博客

    网址:https://blog.csdn.net/qq_62982856/article/details/127768220?spm=1001.2014.3001.5501

12.2.2.1 创建一个新项目student_manage

image-20221108113208391

image-20221108113314571

12.2.2.2 下载jar包

这里我们需要下载三个 jar 包,由于我在这里是直接访问外网,因此如果你的网速不行请切换为流量。

12.2.2.2.1 commons-dbutils-1.7.jar

🏠 下载地址:https://repo1.maven.org/maven2/commons-dbutils/commons-dbutils/1.7/

image-20221108155018788

12.2.2.2.2 druid-1.1.10.jar

🏠 下载地址:https://repo1.maven.org/maven2/com/alibaba/druid/1.1.10/

image-20221108154124914

12.2.2.2.3 mysql-connector-java-xxx.jar

这里需要特别注意,需要下载的数据库驱动jar包根据你的mysql版本会有所不同。

查看自己的mysql版本:mysqld --version

1️⃣ 如果你是mysql5.7的版本

🏠 下载地址:https://repo1.maven.org/maven2/mysql/mysql-connector-java/5.1.37/

image-20221108154813830

2️⃣ 如果你是mysql8.0的版本

🏠 下载地址:https://repo1.maven.org/maven2/mysql/mysql-connector-java/8.0.16/

image-20221108154418137

12.2.2.3 创建管理jar包的文件夹library

1️⃣ 在student_manage文件夹下创建一个library文件夹,将commons-dbutils、druid、mysql-connector-java拷贝到library文件夹下

由于我装的是mysql8.0的版本,因此我使用的jar包时mysql-connector-java-8.0.16.jar

image-20221108155316850

2️⃣ 将jar包添加至项目

image-20221108155537820

image-20221108120421150

image-20221109103820836

12.2.2.4 添加druid.properties文件至src目录下

druid.properties文件内容:(password的值你需要依照自己的实际设置情况来定)

  • 如果你是mysql5.7的版本

    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/student?rewriteBatchedStatements=true&serverTimezone=GMT&useSSL=false
    #数据库用户名
    username=root
    #数据库密码,这里需要依照自己的实际情况
    password=123456
    initialSize=10
    #min idle connecton size
    minIdle=5
    #max active connection size
    maxActive=20
    #max wait time (5000 mil seconds)
    maxWait=5000
    

    image-20221108120712532

  • 如果你是mysql8.0的版本

    driverClassName=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/student?rewriteBatchedStatements=true&serverTimezone=GMT&useSSL=false
    #数据库用户名
    username=root
    #数据库密码,这里需要依照自己的实际情况
    password=123456
    initialSize=10
    #min idle connecton size
    minIdle=5
    #max active connection size
    maxActive=20
    #max wait time (5000 mil seconds)
    maxWait=5000
    

    image-20221108155855159

12.2.2.5 src下创建utils文件夹并创建类

image-20221109104312234

12.2.2.5.1 JDBCUtilsByDruid类
package utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

public class JDBCUtilsByDruid {
    private static DataSource dataSource;
    static{
        try {
            Properties properties = new Properties();
            properties.load(new FileInputStream("src//druid.properties"));
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection(){
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
    //关闭连接
    public static void close(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection){
        try {
            if(resultSet!=null){
                resultSet.close();
            }
            if(preparedStatement!=null){
                preparedStatement.close();
            }
            if(connection!=null){
                connection.close();
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }
}
12.2.2.5.2 ScreenUtils类
package utils;

import java.awt.*;

public class ScreenUtils {


    /*
        获取当前电脑屏幕的宽度
     */
    public static int getScreenWidth(){
        return Toolkit.getDefaultToolkit().getScreenSize().width;
    }

    /*
        获取当前电脑屏幕的高度
     */

    public static int getScreenHeight(){
        return Toolkit.getDefaultToolkit().getScreenSize().height;
    }
}
12.2.2.5.3 StringUtils类
package utils;

/**
 * 字符串工具类
 */
public class StringUtils {
    /**
     * 判断是否 str 是否为合法文本内容
     */
    public static boolean hasText(String str) {
        return str != null && !str.isEmpty() && containsText(str);
    }

    private static boolean containsText(CharSequence str) {
        int strLen = str.length();

        for(int i = 0; i < strLen; ++i) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return true;
            }
        }

        return false;
    }
}

12.2.2.6 src下创建javabean文件夹并在javabean下创建Student类

image-20221109104444052

Student类:

package javabean;

/**
 * 学生类
 */
public class Student {
    /**
     * 学号
     */
    private Integer stuId;
    /**
     * 姓名
     */
    private String name;
    /**
     * 专业
     */
    private String major;
    /**
     * 班级
     */
    private Integer classNum;
    /**
     * 平均成绩
     */
    private Double avgScore;

    public Student() {
    }

    public Student(Integer stuId, String name, String major, Integer classNum, Double avgScore) {
        this.stuId = stuId;
        this.name = name;
        this.major = major;
        this.classNum = classNum;
        this.avgScore = avgScore;
    }

    public Integer getStuId() {
        return stuId;
    }

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

    public String getName() {
        return name;
    }

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

    public String getMajor() {
        return major;
    }

    public void setMajor(String major) {
        this.major = major;
    }

    public Integer getClassNum() {
        return classNum;
    }

    public void setClassNum(Integer classNum) {
        this.classNum = classNum;
    }

    public Double getAvgScore() {
        return avgScore;
    }

    public void setAvgScore(Double avgScore) {
        this.avgScore = avgScore;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuId=" + stuId +
                ", name='" + name + '\'' +
                ", major='" + major + '\'' +
                ", className='" + classNum + '\'' +
                ", avgScore=" + avgScore +
                '}';
    }
}

12.2.2.7 src下创建dao文件夹并创建类和文件夹

image-20221109105624193

12.2.2.7.1 BasicDao类
package dao;

import utils.JDBCUtilsByDruid;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

public class BasicDao<T> {
    private QueryRunner queryRunner = new QueryRunner();
    //dml操作
    public int update(String sql,Object...parameters){
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return queryRunner.update(connection,sql,parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
    //操作多行数据,即返回多个对象
    public List<T> queryMulti(String sql,Class<T> clazz,Object...parameters){
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return queryRunner.query(connection,sql,new BeanListHandler<T>(clazz),parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
    //返回一行数据
    public T querySingle(String sql,Class<T> clazz,Object...parameters){
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return queryRunner.query(connection,sql,new BeanHandler<T>(clazz),parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
    //返回单行单列的结果
    public Object queryScalar(String sql,Object...parameters){
        Connection connection = null;
        try {
            connection = JDBCUtilsByDruid.getConnection();
            return queryRunner.query(connection,sql,new ScalarHandler<>(),parameters);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtilsByDruid.close(null,null,connection);
        }

    }
}
12.2.2.7.2 StudentDao接口
package dao;

import javabean.Student;

import java.util.List;

public interface StudentDao{
    /**
     * 查询信息,按照分数降序排列
     *
     * @return 全部学生信息
     */
    List<Student> queryByScoreDesc();


    /**
     * 添加学生信息
     *
     * @param name 姓名
     * @param stuId 学号
     * @param major 专业
     * @param classNum 班级编号
     * @param avgScore 平均成绩
     */
    void add(String name,Integer stuId,String major,Integer classNum,Double avgScore);

    /**
     * 通过学号查询学生信息
     *
     * @param id 学号
     * @return 学生信息
     */
    Student queryByStuId(Integer id);

    /**
     * 通过学号删除学生信息
     *
     * @param stuId 学号
     */
    void delByStuId(Integer stuId);

    /**
     * 修改学生信息
     *
     * @param name 姓名
     * @param stuId 学号
     * @param major 专业
     * @param classNum 班级编号
     * @param avgScore 平均成绩
     */
    void updateByStuId(String name,Integer stuId,String major,Integer classNum,Double avgScore);
}
12.2.2.7.3 dao下创建impl文件夹并在impl下创建StudentDaoImpl类

image-20221109105059036

StudentDaoImpl类:

package dao.impl;

import dao.BasicDao;
import dao.StudentDao;
import javabean.Student;

import java.util.List;

/**
 * Dao层实现类
 */
public class StudentDaoImpl extends BasicDao<Student> implements StudentDao{
    @Override
    public List<Student> queryByScoreDesc() {
        String sql = "SELECT stu_id AS `stuId`,`name`,major,class_num AS `classNum`,avg_score AS `avgScore`\n" +
                "FROM score ORDER BY avg_score DESC";
        return queryMulti(sql, Student.class);
    }

    @Override
    public void add(String name, Integer stuId, String major, Integer classNum, Double avgScore) {
        String sql = "INSERT INTO score(stu_id,`name`,major,class_num,avg_score) VALUES\n" +
                "(?,?,?,?,?)";
        update(sql,stuId,name,major,classNum,avgScore);
    }

    @Override
    public Student queryByStuId(Integer id) {
        String sql = "SELECT stu_id AS `stuId`,`name`,major,class_num AS `classNum`,avg_score AS `avgScore`\n" +
                "FROM score WHERE stu_id = ?";
        return querySingle(sql,Student.class,id);
    }

    @Override
    public void updateByStuId(String name, Integer stuId, String major, Integer classNum, Double avgScore) {
        String sql = "update score\n" +
                "set `name`= ?\n" +
                ",major = ?\n" +
                ",class_num = ?\n" +
                ",avg_score = ?\n" +
                "WHERE stu_id = ?";
        update(sql,name,major,classNum,avgScore,stuId);
    }

    @Override
    public void delByStuId(Integer stuId) {
        String sql = "DELETE FROM score\n" +
                "WHERE stu_id = ?";
        update(sql, stuId);
    }
}

12.2.2.8 src下创建service文件夹并创建类和文件夹

image-20221109105521599

12.2.2.8.1 StudentService接口
package service;

import javabean.Student;

import java.util.List;

public interface StudentService {
    /**
     * 查询学生信息,按照平均成绩降序排列
     *
     * @return 学生信息
     */
    List<Student> queryByScoreDesc();

    /**
     * 添加学生信息
     *
     * @param name 姓名
     * @param stuId 学号
     * @param major 专业
     * @param classNum 班级编号
     * @param avgScore 平均成绩
     */
    void add(String name, Integer stuId, String major, Integer classNum, Double avgScore);

    /**
     * 通过学号查询学生信息
     *
     * @param id 学号
     * @return 学生信息
     */
    Student queryByStuId(Integer id);

    /**
     * 修改学生信息
     *
     * @param name 姓名
     * @param stuId 学号
     * @param major 专业
     * @param classNum 班级编号
     * @param avgScore 平均成绩
     */
    void updateByStuId(String name,Integer stuId,String major,Integer classNum,Double avgScore);

    /**
     * 通过学号删除学生信息
     *
     * @param id 学号
     */
    void delByStuId(Integer id);
}
12.2.2.8.2 service下创建impl文件夹并在impl下创建StudentServiceImpl类

image-20221109105419624

StudentServiceImpl类:

package service.impl;

import dao.impl.StudentDaoImpl;
import dao.StudentDao;
import javabean.Student;
import service.StudentService;

import java.util.List;

/**
 * Student服务层实现
 */
public class StudentServiceImpl implements StudentService {

    private StudentDao studentDao = new StudentDaoImpl();

    @Override
    public List<Student> queryByScoreDesc() {
        return studentDao.queryByScoreDesc();
    }

    @Override
    public void add(String name, Integer stuId, String major, Integer classNum, Double avgScore) {
        studentDao.add(name, stuId, major, classNum, avgScore);
    }

    @Override
    public Student queryByStuId(Integer id) {
        return studentDao.queryByStuId(id);
    }

    @Override
    public void updateByStuId(String name, Integer stuId, String major, Integer classNum, Double avgScore) {
        studentDao.updateByStuId(name, stuId, major, classNum, avgScore);
    }

    @Override
    public void delByStuId(Integer stuId) {
        studentDao.delByStuId(stuId);
    }
}

12.2.2.9 src下创建component文件夹并在component下创建类

image-20221109110055578

12.2.2.9.1 EditComponent类
package component;

import javabean.Student;
import sun.applet.Main;
import ui.MainFrame;
import utils.StringUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class EditComponent extends JPanel {

    private JFrame jf;

    private JLabel nameLabel;
    private JLabel stuIdLabel;
    private JLabel majorLabel;
    private JLabel classNumLabel;
    private JLabel avgScoreLabel;

    private JTextField nameField;
    private JTextField stuIdField;
    private JTextField majorField;
    private JTextField classNumField;
    private JTextField avgScoreField;

    private JButton addButton;
    private JButton delButton;
    private JButton updateButton;
    private JButton queryButton;

    boolean isQuery;

    private String oldStuId;

    public EditComponent(JFrame jf){
        this.jf = jf;

        //修改布局方式,目的是让表格占满整个JPanel
        this.setLayout(new BorderLayout());

        this.setBackground(new Color(213, 232, 212));

        /*
         * 组装姓名
         */
        Box nameBox = Box.createHorizontalBox();
        nameLabel = new JLabel("姓   名:");
        nameLabel.setFont(new Font("宋体",Font.BOLD,30));
        nameField = new JTextField(18);
        nameField.setFont(new Font("微软雅黑",Font.LAYOUT_NO_LIMIT_CONTEXT,18));
        nameBox.add(nameLabel);
        nameBox.add(Box.createHorizontalStrut(10));
        nameBox.add(nameField);

        /*
         * 组装学号
         */
        Box stuIdBox = Box.createHorizontalBox();
        stuIdLabel = new JLabel("学   号:");
        stuIdLabel.setFont(new Font("宋体",Font.BOLD,30));
        stuIdField = new JTextField(18);
        stuIdField.setFont(new Font("微软雅黑",Font.LAYOUT_NO_LIMIT_CONTEXT,18));

        stuIdBox.add(stuIdLabel);
        stuIdBox.add(Box.createHorizontalStrut(10));
        stuIdBox.add(stuIdField);

        /*
         * 组装专业
         */
        Box majorBox = Box.createHorizontalBox();
        majorLabel = new JLabel("专   业:");
        majorLabel.setFont(new Font("宋体",Font.BOLD,30));
        majorField = new JTextField(18);
        majorField.setFont(new Font("微软雅黑",Font.LAYOUT_NO_LIMIT_CONTEXT,18));

        majorBox.add(majorLabel);
        majorBox.add(Box.createHorizontalStrut(10));
        majorBox.add(majorField);

        /*
         * 组装班级
         */
        Box classNumBox = Box.createHorizontalBox();
        classNumLabel = new JLabel("班   级:");
        classNumLabel.setFont(new Font("宋体",Font.BOLD,30));

        classNumField = new JTextField(18);
        classNumField.setFont(new Font("微软雅黑",Font.LAYOUT_NO_LIMIT_CONTEXT,18));

        classNumBox.add(classNumLabel);
        classNumBox.add(Box.createHorizontalStrut(10));
        classNumBox.add(classNumField);

        /*
         * 组装平均成绩
         */
        Box avgScoreBox = Box.createHorizontalBox();
        avgScoreLabel = new JLabel("平均成绩:");
        avgScoreLabel.setFont(new Font("宋体",Font.BOLD,28));

        avgScoreField = new JTextField(10);
        avgScoreField.setFont(new Font("微软雅黑",Font.LAYOUT_NO_LIMIT_CONTEXT,18));

        avgScoreBox.add(avgScoreLabel);
        avgScoreBox.add(Box.createHorizontalStrut(7));
        avgScoreBox.add(avgScoreField);

        /*
         组装左侧
         */
        Box leftBox = Box.createVerticalBox();
        leftBox.add(Box.createVerticalStrut(60));
        leftBox.add(nameBox);
        leftBox.add(Box.createVerticalStrut(25));
        leftBox.add(stuIdBox);
        leftBox.add(Box.createVerticalStrut(25));
        leftBox.add(majorBox);
        leftBox.add(Box.createVerticalStrut(25));
        leftBox.add(classNumBox);
        leftBox.add(Box.createVerticalStrut(25));
        leftBox.add(avgScoreBox);

        /*
        组装右侧
         */
        Box rightBox = Box.createVerticalBox();
        addButton = new JButton("添加");
        delButton = new JButton("删除");
        updateButton = new JButton("修改");
        queryButton = new JButton("查询");

        //添加按钮增添监听事件
        addButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                isQuery = false;
                String name = nameField.getText().trim();
                String stuId = stuIdField.getText().trim();
                String major = majorField.getText().trim();
                String classNum = classNumField.getText().trim();
                String avgScore = avgScoreField.getText().trim();
                //判断内容是否合理并不为空
                if(!StringUtils.hasText(name)||!StringUtils.hasText(stuId)||!StringUtils.hasText(major)||
                        !StringUtils.hasText(classNum)||!StringUtils.hasText(avgScore)){
                    JOptionPane.showMessageDialog(jf,"您有空内容或不合理内容,请修改","提醒",JOptionPane.WARNING_MESSAGE);
                    return;
                }

                Integer stuIdParse = null;
                Integer classNumParse = null;
                Double avgScoreParse = null;
                try {
                    stuIdParse = Integer.parseInt(stuId);
                    if(stuIdParse<20000000){
                        JOptionPane.showMessageDialog(jf,"添加失败,错误的学号信息","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                    classNumParse = Integer.parseInt(classNum);
                    if(classNumParse<1){
                        JOptionPane.showMessageDialog(jf,"添加失败,错误的班级信息","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                    avgScoreParse = Double.parseDouble(avgScore);
                    if(avgScoreParse<0||avgScoreParse>100){
                        JOptionPane.showMessageDialog(jf,"添加失败,成绩应在0~100之间","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                    Student student = MainFrame.studentService.queryByStuId(stuIdParse);
                    if(student!=null){
                        //说明该学号已经存在了
                        JOptionPane.showMessageDialog(jf,"添加失败,学号 "+stuIdParse+" 已存在","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(jf,"您有空内容或不合理内容,请修改","提醒",JOptionPane.WARNING_MESSAGE);
                    return;
                }

                try {
                    MainFrame.studentService.add(name,stuIdParse,major,classNumParse,avgScoreParse);
                    JOptionPane.showMessageDialog(jf,"添加成功","提醒",JOptionPane.INFORMATION_MESSAGE);
                    clearTextField();
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(jf,ex.getMessage(),"错误",JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        //修改按钮增添监听事件
        updateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(!isQuery){
                    JOptionPane.showMessageDialog(jf,"请先查询到该学号原信息再进行修改操作","提醒",JOptionPane.WARNING_MESSAGE);
                    return;
                }

                if(!stuIdField.getText().equals(oldStuId)){
                    JOptionPane.showMessageDialog(jf,"学号不可修改或请先查询到该学号原信息再进行修改操作","提醒",JOptionPane.WARNING_MESSAGE);
                    isQuery = false;
                    return;
                }

                String name = nameField.getText().trim();
                String stuId = stuIdField.getText().trim();
                String major = majorField.getText().trim();
                String classNum = classNumField.getText().trim();
                String avgScore = avgScoreField.getText().trim();
                //判断内容是否合理并不为空
                if(!StringUtils.hasText(name)||!StringUtils.hasText(stuId)||!StringUtils.hasText(major)||
                        !StringUtils.hasText(classNum)||!StringUtils.hasText(avgScore)){
                    JOptionPane.showMessageDialog(jf,"您有空内容或不合理内容,请修改","提醒",JOptionPane.WARNING_MESSAGE);
                    return;
                }

                Integer stuIdParse = null;
                Integer classNumParse = null;
                Double avgScoreParse = null;
                try {
                    stuIdParse = Integer.parseInt(stuId);
                    if(stuIdParse<20000000){
                        JOptionPane.showMessageDialog(jf,"修改失败,错误的学号信息","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                    classNumParse = Integer.parseInt(classNum);
                    if(classNumParse<1){
                        JOptionPane.showMessageDialog(jf,"修改失败,错误的班级信息","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                    avgScoreParse = Double.parseDouble(avgScore);
                    if(avgScoreParse<0||avgScoreParse>100){
                        JOptionPane.showMessageDialog(jf,"修改失败,成绩应在0~100之间","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                    Student student = MainFrame.studentService.queryByStuId(stuIdParse);
                    if(student==null){
                        //说明该学号不存在
                        JOptionPane.showMessageDialog(jf,"修改失败,学号 "+stuIdParse+" 不存在","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(jf,"您有空内容或不合理内容,请修改","提醒",JOptionPane.WARNING_MESSAGE);
                    return;
                }

                try {
                    MainFrame.studentService.updateByStuId(name,stuIdParse,major,classNumParse,avgScoreParse);
                    JOptionPane.showMessageDialog(jf,"修改成功","提醒",JOptionPane.INFORMATION_MESSAGE);
                    clearTextField();
                    isQuery = false;
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(jf,ex.getMessage(),"错误",JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        //删除按钮增添监听事件
        delButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                String stuId = stuIdField.getText().trim();
                if(!StringUtils.hasText(stuId)){
                    JOptionPane.showMessageDialog(jf,"空或不合理的学号,请修改","提醒",JOptionPane.WARNING_MESSAGE);
                    return;
                }
                Integer stuIdParse = null;
                try {
                    stuIdParse = Integer.parseInt(stuId);
                    if(stuIdParse<20000000){
                        throw new RuntimeException();
                    }
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(jf,"空或不合理的学号,请修改","提醒",JOptionPane.WARNING_MESSAGE);
                    return;
                }
                try {
                    Student student = MainFrame.studentService.queryByStuId(stuIdParse);
                    if(student==null){
                        JOptionPane.showMessageDialog(jf,"该学号信息不存在","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                    int option = JOptionPane.showConfirmDialog(jf, "您确定删除学号为 " + stuId + " 的数据信息吗", "确定栏", JOptionPane.YES_NO_OPTION);
                    if(option==JOptionPane.YES_OPTION){
                        MainFrame.studentService.delByStuId(stuIdParse);
                        JOptionPane.showMessageDialog(jf,"删除成功","提醒",JOptionPane.INFORMATION_MESSAGE);
                        clearTextField();
                        isQuery = false;
                    }
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(jf,ex.getMessage(),"错误",JOptionPane.ERROR_MESSAGE);
                }
            }
        });

        //查询按钮增添监听事件
        queryButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String stuId = stuIdField.getText().trim();
                if(!StringUtils.hasText(stuId)){
                    JOptionPane.showMessageDialog(jf,"空或不合理的学号,请修改","提醒",JOptionPane.WARNING_MESSAGE);
                    return;
                }
                Integer stuIdParse = null;
                try {
                    stuIdParse = Integer.parseInt(stuId);
                    if(stuIdParse<20000000){
                        throw new RuntimeException();
                    }
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(jf,"空或不合理的学号,请修改","提醒",JOptionPane.WARNING_MESSAGE);
                    return;
                }
                try {
                    Student student = MainFrame.studentService.queryByStuId(stuIdParse);
                    if(student==null){
                        JOptionPane.showMessageDialog(jf,"该学号信息不存在","提醒",JOptionPane.WARNING_MESSAGE);
                        return;
                    }
                    nameField.setText(student.getName());
                    classNumField.setText(student.getClassNum()+"");
                    stuIdField.setText(student.getStuId()+"");
                    majorField.setText(student.getMajor());
                    avgScoreField.setText(student.getAvgScore()+"");
                } catch (Exception ex) {
                    JOptionPane.showMessageDialog(jf,ex.getMessage(),"错误",JOptionPane.ERROR_MESSAGE);
                    return;
                }

                //表明已查询到
                isQuery = true;
                oldStuId = stuIdField.getText();

            }
        });

        rightBox.add(Box.createVerticalStrut(72));
        rightBox.add(addButton);
        rightBox.add(Box.createVerticalStrut(60));
        rightBox.add(delButton);
        rightBox.add(Box.createVerticalStrut(60));
        rightBox.add(updateButton);
        rightBox.add(Box.createVerticalStrut(60));
        rightBox.add(queryButton);


        /*
        组装全部
         */
        Box allBox = Box.createHorizontalBox();
        allBox.add(leftBox);
        allBox.add(Box.createHorizontalStrut(100));
        allBox.add(rightBox);

        Panel mainPanel = new Panel();
        mainPanel.add(allBox);
        this.add(mainPanel);
    }

    /**
     * 清空文本域内容
     */
    public void clearTextField(){
        nameField.setText("");
        classNumField.setText("");
        stuIdField.setText("");
        majorField.setText("");
        avgScoreField.setText("");
    }

}
12.2.2.9.2 ScoreComponent类
package component;

import javabean.Student;
import ui.MainFrame;

import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
import java.awt.*;
import java.util.*;
import java.util.List;

public class ScoreComponent extends JPanel {

    private JTable jTable;
    private Vector<String> titles = new Vector<>(Arrays.asList("学号", "姓名", "专业", "班级", "平均成绩"));
    private Vector<Vector> tableData;
    private TableModel tableModel;

    private JFrame jf;

    // 设置表格间隔色
    MyDefaultTableCellRenderer ter = new MyDefaultTableCellRenderer();

    public ScoreComponent(JFrame jf) {
        this.jf = jf;

        //修改布局方式,目的是让表格占满整个JPanel
        this.setLayout(new BorderLayout());

        tableData = new Vector<>();

        tableModel = new DefaultTableModel(tableData, this.titles);


        jTable = new JTable(tableModel) {
            @Override
            public boolean isCellEditable(int row, int column) {
                //设置为均不可直接修改
                return false;
            }
        };

        requestData();

        //颜色渲染
        for (int i = 0; i < this.titles.size(); i++) {
            jTable.getColumn(this.titles.get(i)).setCellRenderer(ter);
        }

        //设置只能选中一行
        //jTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);

        /*
           美化表头
         */
        JTableHeader header = jTable.getTableHeader();
        //表头的高
        header.setPreferredSize(new Dimension(1, 50));
        //表头的背景颜色
        header.setBackground(new Color(229,239,255));
        //设置表头字体
        header.setFont(new Font("STLiti", Font.BOLD, 20));

        //设置字体
        jTable.setFont(new Font("STHeiti", Font.PLAIN, 20));

        //设置行高
        jTable.setRowHeight(30);

        //支持滚动条浏览表格
        JScrollPane jScrollPane = new JScrollPane(jTable);
        jScrollPane.getVerticalScrollBar().setUI(new NewScrollBarUI());
        this.add(jScrollPane);
    }

    public void requestData() {
        List<Student> students = null;
        try {
            students = MainFrame.studentService.queryByScoreDesc();
        } catch (Exception e) {
            JOptionPane.showMessageDialog(jf,"网络连接超时,无法获取新数据,请稍后再试","提示",JOptionPane.ERROR_MESSAGE);
            return;
        }
        //清空tableData的数据
        tableData.clear();

        for (Student student : students) {
            Vector vector = new Vector();
            vector.add(student.getStuId());
            vector.add(student.getName());
            vector.add(student.getMajor());
            vector.add(student.getClassNum());
            vector.add(student.getAvgScore());
            tableData.add(vector);
        }

        jTable.updateUI();
    }


    class MyDefaultTableCellRenderer extends DefaultTableCellRenderer {
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
                                                       boolean hasFocus, int row, int column) {
            // table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
            if (row % 2 == 0) {
                setBackground(Color.pink);
            } else if (row % 2 == 1) {
                setBackground(Color.white);
            }
            return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
        }
    }
}
12.2.2.9.3 NewScrollBarUI类
package component;



import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JScrollBar;
import javax.swing.plaf.basic.BasicScrollBarUI;

/**
 * 自定义滚动条UI
 */
public class NewScrollBarUI extends BasicScrollBarUI {

    @Override
    protected void configureScrollBarColors() {

        // 把手

        // thumbColor = Color.GRAY;

        // thumbHighlightColor = Color.BLUE;

        // thumbDarkShadowColor = Color.BLACK;

        // thumbLightShadowColor = Color.YELLOW;

        // 滑道
        if (this.scrollbar.getOrientation() == JScrollBar.VERTICAL) {
            trackColor = Color.black;

            setThumbBounds(0, 0, 3, 10);
        }
        if (this.scrollbar.getOrientation() == JScrollBar.HORIZONTAL) {
            trackColor = Color.black;

            setThumbBounds(0, 0, 10, 3);
        }
        // trackHighlightColor = Color.GREEN;

    }

    /**
     * 设置滚动条的宽度
     */

    @Override
    public Dimension getPreferredSize(JComponent c) {

        // TODO Auto-generated method stub
        if (this.scrollbar.getOrientation() == JScrollBar.VERTICAL) {
            c.setPreferredSize(new Dimension(10, 0));
        }
        if (this.scrollbar.getOrientation() == JScrollBar.HORIZONTAL) {

            c.setPreferredSize(new Dimension(0, 6));
        }

        return super.getPreferredSize(c);
    }


    // 重绘滑块的滑动区域背景

    public void paintTrack(Graphics g, JComponent c, Rectangle trackBounds) {

        Graphics2D g2 = (Graphics2D) g;

        GradientPaint gp = null;

        //判断滚动条是垂直的 还是水平的

        if (this.scrollbar.getOrientation() == JScrollBar.VERTICAL) {

            //设置画笔

            gp = new GradientPaint(0, 0, Color.decode("#ede95f"),

                    trackBounds.width, 0, Color.decode("#ff0000"));

        }

        if (this.scrollbar.getOrientation() == JScrollBar.HORIZONTAL) {

            /*gp = new GradientPaint(0, 0, new Color(80, 80, 80),

                    trackBounds.height, 0, new Color(80, 80, 80));*/
            gp = new GradientPaint(0, 0, Color.decode("#007C8E"),

                    trackBounds.width, 0, Color.decode("#007C8E"));

        }


        g2.setPaint(gp);

        //填充Track

        g2.fillRect(trackBounds.x, trackBounds.y, trackBounds.width,

                trackBounds.height);

        //绘制Track的边框
        /*       g2.setColor(new Color(175, 155, 95));
         g2.drawRect(trackBounds.x, trackBounds.y, trackBounds.width - 1,
                trackBounds.height - 1);
                */

        if(trackHighlight == BasicScrollBarUI.DECREASE_HIGHLIGHT) {

            this.paintDecreaseHighlight(g);
        }

        if(trackHighlight == BasicScrollBarUI.INCREASE_HIGHLIGHT) {

            this.paintIncreaseHighlight(g);
        }

    }


    @Override
    protected void paintThumb(Graphics g, JComponent c, Rectangle thumbBounds) {

        // 把绘制区的x,y点坐标定义为坐标系的原点

        // 这句一定一定要加上啊,不然拖动就失效了

        g.translate(thumbBounds.x, thumbBounds.y);

        // 设置把手颜色

        g.setColor(Color.decode("#4507ff"));

        // 画一个圆角矩形

        // 这里面前四个参数就不多讲了,坐标和宽高

        // 后两个参数需要注意一下,是用来控制角落的圆角弧度

        // g.drawRoundRect(0, 0, 5, thumbBounds.height - 1, 5, 5);

        // 消除锯齿

        Graphics2D g2 = (Graphics2D) g;

        RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,

                RenderingHints.VALUE_ANTIALIAS_ON);

        g2.addRenderingHints(rh);

        // 半透明

        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,

                0.5f));

        // 设置填充颜色,这里设置了渐变,由下往上

        // g2.setPaint(new GradientPaint(c.getWidth() / 2, 1, Color.GRAY,

        // c.getWidth() / 2, c.getHeight(), Color.GRAY));

        // 填充圆角矩形
        if (this.scrollbar.getOrientation() == JScrollBar.VERTICAL) {
            g2.fillRoundRect(0, 0, 40, thumbBounds.height - 1, 5, 5);
        }
        if (this.scrollbar.getOrientation() == JScrollBar.HORIZONTAL) {
            g2.fillRoundRect(0, 0, thumbBounds.width - 1, 40, 5, 5);
        }
    }


    /**
     * 创建滚动条上方的按钮
     */

    @Override

    protected JButton createIncreaseButton(int orientation) {

        JButton button = new JButton();

        button.setBorderPainted(false);

        button.setContentAreaFilled(false);

        button.setBorder(null);

        return button;

    }

    /**
     * 创建滚动条下方的按钮
     */

    @Override

    protected JButton createDecreaseButton(int orientation) {

        JButton button = new JButton();

        button.setBorderPainted(false);

        button.setContentAreaFilled(false);

        button.setFocusable(false);

        button.setBorder(null);

        return button;

    }
}

12.2.2.10 src下创建ui文件夹并在src下创建类

image-20221109110252411

MainFrame:

package ui;

import component.EditComponent;
import component.ScoreComponent;
import service.impl.StudentServiceImpl;
import service.StudentService;
import utils.ScreenUtils;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

/**
 * 主界面
 */
public class MainFrame {
    public static StudentService studentService = new StudentServiceImpl();

    JFrame jf = new JFrame("学生成绩管理系统");

    /**
     * 定义窗口的宽度
     */
    final int WIDTH = 700;
    /**
     * 定义窗口的高度
     */
    final int HEIGHT = 500;

    /**
     * 创建工具条
     */
    JToolBar jToolBar;
    JButton showButton;
    JButton editButton;

    JPanel mainPanel;

    /**
     * 当前是成绩模块还是编辑模块
     */
    String module = "学生成绩";

    /**
     * 默认是成绩模块
     */
    ScoreComponent scoreComponent;
    EditComponent editComponent;



    public void init(){
        //设置关闭窗口为结束程序
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        //设置窗口相关的属性
        jf.setBounds((ScreenUtils.getScreenWidth() - WIDTH) / 2, (ScreenUtils.getScreenHeight() - HEIGHT) / 2, WIDTH, HEIGHT);

        //设置窗口大小不可变
        jf.setResizable(false);

        /*
         * 组装工具条
         */
        jToolBar = new JToolBar();
        showButton = new JButton("学生成绩");
        editButton = new JButton("编辑");

        //对 点击 学生成绩按钮 的处理 --> 刷新数据
        showButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if(e.getActionCommand().equals(module)){
                    //说明原本就是在学生成绩模块
                    //那么只需要重新获取数据
                    scoreComponent.requestData();
                }else{
                    //修改 module
                    module = "学生成绩";

                    //去除editComponent
                    mainPanel.remove(editComponent);
                    //加入scoreComponent
                    mainPanel.add(scoreComponent);
                    scoreComponent.requestData();
                    //刷新页面,重绘面板
                    mainPanel.repaint();
//                    //使重绘的面板确认生效
                    mainPanel.validate();
                }
            }
        });

        //对 点击 编辑模块 的处理
        editButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (!module.equals("编辑")) {
                    //修改 module
                    module = "编辑";

                    //移除面板中的组件
                    mainPanel.remove(scoreComponent);
                    //添加要切换的面板
                    mainPanel.add(editComponent);
                    //刷新页面,重绘面板
                    mainPanel.repaint();
                    //使重绘的面板确认生效
                    mainPanel.validate();
                }
            }
        });

        jToolBar.add(showButton);
        jToolBar.addSeparator();
        jToolBar.add(editButton);

        //设置工具条背景颜色
        jToolBar.setBackground(new Color(197,255,103));

        //向窗口中添加工具条
        jf.add(jToolBar, BorderLayout.NORTH);

        scoreComponent = new ScoreComponent(jf);
        editComponent = new EditComponent(jf);

        mainPanel = new JPanel(new BorderLayout());

        //默认是成绩面板
        mainPanel.add(scoreComponent);

        jf.add(mainPanel);

        jf.setVisible(true);
    }
}

12.2.2.11 src下创建主启动类

image-20221109110617090

StudentManageApplication类:

import ui.MainFrame;

/**
 * 主启动类
 */
public class StudentManageApplication {
    public static void main(String[] args) {
        new MainFrame().init();
    }
}

12.2.2.12 注意事项与细节说明

  1. 在运行主启动类StudentManageApplication需要确保开启了MySQL服务:win+R输入services.msc查看:

    image-20221109124907929

  2. 如何查看自己的MySQL版本:mysqld --version

    image-20221109125104319

本文含有隐藏内容,请 开通VIP 后查看