学生信息管理系统

文章目录

仓库链接🔗

https://gitee.com/honiestbutter/student-management-system

功能构架图

学生信息管理系统

基层构建util.sql

⭐️DAO模式

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WyqYl1Cl-1625040913532)(/Users/zhangzihan/Library/Application Support/typora-user-images/截屏2021-06-25 上午8.21.25.png)]

数据库内容

由于我的这个成绩管理系统是以数据库为基础的,所有对数据进行的增删减改操作都是直接对数据库操作,所以java对数据库命令操作的是在最底层的,前段按钮所有的命令根源都要传输到底层包装中,转化成对数据的命令来进行对数据库的操作,实现最终目的。

在数据库中我建立了两个表格,一个名为all用来储存学生信息,一个是user用来储存登陆的用户名信息。

登陆数据库

  1. 打开数据库所在的目录
  2. 弹出输入密码
zhangzihan@zhangzihandeMacBook-Air ~ % cd /usr/local/mysql/bin //打开目录  
zhangzihan@zhangzihandeMacBook-Air bin % ./mysql -u root -p  //输入命令
Enter password: //输入密码
//有以下显示表示成功打开数据库
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 15
Server version: 8.0.25 MySQL Community Server - GPL

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

建立表格

Student信息表格
(
    `id`       BIGINT      NOT NULL AUTO_INCREMENT,
    `name`     VARCHAR(20) NOT NULL,
    `gender`   VARCHAR(10) NOT NULL,
    `classname`  VARCHAR(20) NOT NULL,
    `math`     INT DEFAULT 0,
    `java`     INT DEFAULT 0,
    `pe`       INT DEFAULT 0,
    `sumscore` INT DEFAULT 0,
    PRIMARY KEY (`id`),
    UNIQUE KEY (`id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1000001
  DEFAULT CHARSET = utf8;

截屏2021-06-30 上午11.51.18

User信息表格

前端与后端的连接,转化为数据库命令我主要是通过:

前端组件触发事件,获取信息分类传送给相应的类和方法,提取出参数和要实现的功能(要进行的操作),然后只需要将相应参数传给后端,就可以实现对数据库的操作

(因为只用到了一个数据库,所以没有定义DAO接口,最基层的就是数据库的具体实现类)

核心BaseDAO类——数据库的具体实现

在基类BaseDAO中,把对数据库的操作都封装到方法中

👍🏽1:getBd()方法——实现只创建一次对象,提高内存利用率

👍🏿2:getCon() 方法——只创建一次对数据库的连接,后面都利用这个连接,提高速率

 if(con==null||con.isClosed()){      con=DriverManager.getConnection(url,usename,password);//2.只需要第一次的时候建立连接
}

后期需要具体了解的方法:(这里不详说了)

1.数据库的连接口令
2.查找query
3.修改(添加删除修改)upgrade

DAO接口manage DAO

1.继承接口方法

StudentDAOuserDAO都继承manageDAO接口,实现与数据库底层的操作,接口中的方法:

  1. ⭐️final BaseDAO bd = BaseDAO.getBd();

    通过BaseDAO方法获得BaseDAO对象而不是new——优点:

    1. 避免对数据库进行操作时,多次重复新建对象造成内存的占用和浪费,这样相当于只创建一次对象

    2. 避免对数据库重复的连接和关闭——数据库的连接过程其实是很消耗资源的,这样只创建一次BaseDAO对象相当于只要打开数据库就不关闭了

    3. 保护BaseDAO类中的私有变量

       public  static BaseDAO getBd(){//返回对象
              if(bd==null){
                  bd=new BaseDAO();
              }
              return bd;
          }
          //只有第一次的时候需要new一个对象,后面都使用这个对象,降低内存占用(避免重复新建对象)
      
  2. void closeAll();关闭数据库

2.为什么要建立这个接口

实现分工

因为StudentDAOmanageDAO类有共同的特征,都要通过BaseDAO实现对数据库的操作,这两个类的作用都是==实体类:实现存放和传输具体数据==,只不过接收的数据种类不同,StudentDAO转化的是学生信息,userDAO转化的是用户账号密码信息。

通过建立这个接口,提取共同实现的功能,降低代码的重复性耦合性,提高重复利用率。

实体类1:userDAO——对用户信息的分析

按下注册按钮和登陆按钮时需要对用户信息分析

登陆:

​ 用户名是否存在and密码是否与用户名相匹配——BaseDAO查找功能

registerDialog注册界面

  1. ⭐️三个文本框不能为空
  2. 用户名不能已存在——BaseDAO查找功能
  3. 密码两次输入要统一

实体类2:StudentDAO——对学生信息的分析

⚠️:只有与数据库有关的对信息的分析和处理的方法可以放在StudentDAOUserDAO

JNI

JNI是Java调用C或C++程序的一种技术

创建JNI接口

新建一个类,在类中声明带有native关键词的方法,那么这个方法就是接下来要在C\Cpp程序中要调用的函数

public class RandomGenerate {
    public native void get();//调用native本地方法————调用C++程序
}

随后让终端来该改类所在的文件夹,输入

javac -h . 类名.class

随后会在该目录下的到一个.h的头文件,这个文件就是Java和C/Cpp程序进行交互的接口啦

编写C++程序
  1. 在提供的.h头文件中,会出现一个已经定义好的函数,这个就是咱们要实现的函数。
JNIEXPORT void JNICALL Java_util_random_RandomGenerate_get
  (JNIEnv *, jobject);
//java中定义的native方法对应在C++文件中就是这个函数

  1. C++文件Cachieve中实现的不再是int main()而是以这个.h文件中生成的函数下的函数体

  2. C++文件实现的事随机生成数据输出到文件中

  3. 在实现完函数之后,执行编译命令——生成.so文件

clang++ -o2 -I"/Library/Java/JavaVirtualMachines/liberica-jdk-11-full.jdk/Contents/Home/include" -I"/Library/Java/JavaVirtualMachines/liberica-jdk-11-full.jdk/Contents/Home/include/darwin" -shared -o getRandom.so a.cpp

-o2是开启编译优化,提高程序运行速度;-shared是创建动态链接库,供JVM虚拟机调用。

在java程序中调用编译好的C++文件

复制编译好的程序的具体目录和名称,在要调用的代码中写下如下:

class 类名 {
    static {
        System.load("目录名和文件名");
    }
}

随后再调用就行啦

输出栏显示进度

截屏2021-06-30 下午12.11.23

整体框架

整体分为了三个包,face包中实现的主要是登陆界面loginWindow和注册界面registerWindow的完善

登陆之后进入主界面,有三个大模块构成(三个包实现)——

  1. 学生成绩概览GradeChart

  2. 图例化分析

  3. 生成海量数据

loginWindow

这个窗口比较简单,实现的主要是javaSwing的应用进行布局

单击两个按钮产生的Actionevent事件,生成两个窗口

单击登陆会产生对输入的用户名和密码的信息判断——UserDAO

登陆界面

登陆界面

如果用户名密码不匹配提示错误

注册界面

如果什么都不输入直接注册的话会错误提示

用户名已存在也会错误提示

两次密码输入不一致错误提示

登陆成功后进入主界面MainWindow

MainWindow

截屏2021-06-30 上午11.59.36

进入到gradeChart

gradeChart界面

截屏2021-06-25 下午12.12.48

1️⃣JTable——实现数据库内容输出到java页面表格

  private JTable gradeTable;
  private DefaultTableModel gradeTableModel;

DefaulttableModel

DefaulttableModel的对象规定的是表格格式

 gradeTableModel = new DefaultTableModel(stuTools.studentList(StudentDAO.ORDER_BY_ID), head) {//DefaultTableModel是Table的子接口

new构造方法中传入:

  1. 表格内容(二维数组)——🎃从数据库中调出的表格(调用方法返回特定符合条件的数组作为参数)
  2. 表头head(字符串一维数组)

Jtable

DefaulttableModel对象规定的表格格式建立表格

gradeTable = new JTable(gradeTableModel);

构造方法中传入的DefaulttableModel对象(规定表格格式)

table表格放入JscrollPane

否则表格不会显示,这个我也不知道为什么。

 scrollPane = new JScrollPane(gradeTable);
 add(scrollPane, BorderLayout.CENTER);

Actionevent

ActionEvent包含一个事件,该事件为执行动作事件ACTION_PERFORMED.

触发这个事件的动作为:

  1. 点击按钮
  2. 双击列表中选项——改写学生信息用到
  3. 选择菜单项——精确查找和按需输出时用到
  4. 在文本框中输入回车——暂时没用到

2️⃣添加add

获得文本框中输入的所有信息放到数组中,传送给StudentDAO中的插入命令insert(String inf[])

⭐️刷新新建信息后的table表

方法:每创建成功后,调用方法把数据库中的信息再倒入到table中一遍,实现刷新

 if(sd.insert(inf)){
            gc.updateGradeTable();//🔺更新数据
刷新table方法updateGadeTable()
 public void updateGradeTable() {//获得table的DefaultTableModel格式
        gradeTableModel.setDataVector(stuTools.studentList(StudentDAO.ORDER_BY_ID), head);
        //重写从数据库中拉取数据,获得更新🔺
    }
DefaultTableModel.setDataVector()方法

DefaultTableModel.setDataVector(Object[][]dataVector,Object []head)

用数组 dataVector 中的值替换 dataVector 实例变量中的值,表头为head

3️⃣删除delete

⭐️获得所点击的table列的学生信息

     int row = gradeTable.getSelectedRow();

既要在数据库中实现学生信息的修改(StudentDAO的delete方法),又要在table中实现

table中删除信息(行)

  ((DefaultTableModel) gradeTable.getModel()).removeRow(row);

4️⃣修改rewrite

一.两种触发修改事件的方式:

2.双击学生信息

⭐️实现方法:给table增加一个鼠标事件判断——如果检测到点击次数两次,就触发和点击修改按钮同样的事件,弹出修改窗口

 gradeTable.addMouseListener(new MouseAdapter() {//鼠标事件
            @Override
            public void mouseClicked(MouseEvent e) {
                if(e.getClickCount() > 1) {//如果双击
                    rewriteButton.doClick();//触发点击rewrite的功能🔺
                }
            }
        })

🔺同时要修改gradeTableModel的构造方法:因为默认是双击修改单元格内容,要改成双击打开修改框,所以要关闭这个功能

 gradeTableModel = new DefaultTableModel(stuTools.studentList(StudentDAO.ORDER_BY_ID), head) {//DefaultTableModel是Table的子接口
            @Override
            public boolean isCellEditable(int row, int column) {//重写接口中的方法——双击窗口不能修改表格中的内容
                return false;
            }
            //默认可以修改(但是想要实现双击激发rewrite重写按钮同时实现重写数据库和表格的内容,这里冲突(只能重写表格中的内容))
        };
2. 点击修改按钮

修改框和增加框类似,都是获得文本框信息,只不过修改框调用的是update方法

二.仅刷新更改的这一行信息(实现对table中内容的更改)

int row = table.getSelectedRow();
        for (int i = 0; i < table.getColumnCount(); i++) {
            table.setValueAt(inf[i], row, i);//🔺仅刷新这一行的数据

5️⃣精确查找find

注意错误信息提醒

  1. 如果两个选项都没有选择的时候,JRadioButton返回的是-1,需要进行提示。

  2. 如果没查到,返回的结果数组长度为0,需要提示信息

    if(stu.length>0){      
        ((DefaultTableModel)table.getModel()).setDataVector(stu, head);    }
    else{        
        JOptionPane.showMessageDialog(null,"未找到学生信息!","Sorry",JOptionPane.ERROR_MESSAGE);    }
    
  3. ID必须是数字串

  4. 输入内容不能为空

查找成功后都要刷新table表

 final var stu=sd.findStudent( contentField.getText(), StudentDAO.FIND_BY_ID);
    if(stu.length>0){
        ((DefaultTableModel)table.getModel()).
                setDataVector(stu, head);
    }

6️⃣按需求展示信息class

7️⃣生成个人/班级成绩详细对比表

截屏2021-06-30 下午12.13.06

班级为单位:

截屏2021-06-30 下午12.14.05

个人为单位:

截屏2021-06-30 下午12.17.37

8️⃣数据可视化(柱状图)

9️⃣输出到EXCEL表(print)

POI操作

新建一个线程——提高运行速度

截屏2021-06-30 下午12.20.45

  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值