ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java学生信息管理系统课设实战:eclipse+MySQL+JDBC完整实现

Java学生信息管理系统课设实战:eclipse+MySQL+JDBC完整实现 简介一份基于Eclipse与MySQL的Java学生信息管理系统项目包面向正在学习Java SE与数据库编程的初学者适合作为课程设计或练手项目。系统实现了登录注册、管理员/教师/学生三种身份鉴权以及学生信息和成绩信息的增删改查操作管理员与教师具备修改权限学生仅可查询覆盖了基础管理系统的典型业务闭环。压缩包共44个文件以17个Java源文件与18个编译后的class文件为主另含连接MySQL所需的forms与miglayout相关jar库、项目配置文件及少量示例图片整体大小仅616KB结构清晰便于直接导入Eclipse运行。已有6474名学习者查看或下载代码中可看到miglayout-src等依赖源码包便于排查运行时环境问题。对于刚接触Java Swing或MySQL交互的读者这套项目能帮助理解登录权限设计、DAO分层与界面事件处理等实用知识点。1. Java学生信息管理系统eclipse MySQL 课设背后的真实工程量“Java学生信息管理系统eclipseMySQL”是很多学校课程设计的固定题目。需求其实不算复杂录入学生基本信息支持增删改查登录后进入主界面。但真正让人卡住的往往是流程产物——既要能覆盖 eclipse 导入项目、MySQL 建库、JDBC 连接这些环节又要代码结构清爽到能应对答辩。这套课设资源把数据库脚本、源码、界面类和说明文档放在一起你可以直接照步骤复现从环境变量配置一路跑到功能可用。适合两类人一类是拿它交作业的按本文走一遍心里就有底另一类是想弄明白 Swing MySQL 整合到底是怎么串起来的。2. 环境搭建与版本搭配先解决 JDK、eclipse、MySQL 三个安装难点2.1 JDK 与 eclipse 的版本匹配环境变量配置先走一遍安装 eclipse 之前最容易出错的步骤是 JDK 版本没选对。典型场景是电脑里装过多个 JDK命令行下 java -version 显示的还是老版本而 eclipse 里配置的 JRE 又指向另一个路径编译时就会冒出各种 validate 错误。我一般会先把 JDK 定下来。课设项目建议直接用 JDK 81.8或者 JDK 17 搭配新一点的 eclipse 版本。JDK 8 在课程设计和不少企业环境里覆盖率最高MySQL 驱动和它兼容性最好没必要追最新的 JDK 21。确定版本后配置环境变量新增 JAVA_HOME 指向 JDK 安装目录比如C:\Program Files\Java\jdk1.8.0_202在 Path 变量里追加%JAVA_HOME%\bin。配置完成后命令行敲java -version和javac -version两个都能输出版本号才算环境变量配置成功。这一步漏了eclipse 里建项目还能编译但命令行跑脚本或后续排查问题时就容易翻车。eclipse 本身是绿色版解压后双击 eclipse.exe 就能用。首次启动会让你选工作空间workspace路径里尽量不要带中文和空格不然部分插件在生成路径时会有编码问题。从网上下载的源码包解压后如果目录里缺了.project和.classpath文件直接 Import → Existing Projects into Workspace 会失败。这种情况先新建一个 Java 项目再用 Import → File System 把源码导入或者手动补齐项目配置文件。这章节还要提一个常见误区eclipse 里打开的代码明明和源码包一致但运行结果不对。原因多半是工作空间缓存了旧版本处理办法是 Project → Clean把该项目的编译输出清掉再重新编译。这个操作的成本很低遇到运行结果诡异时优先试它。2.2 MySQL 安装与初始化8.0 还是 5.7装完怎么验证数据库这边建议用 MySQL 8.0 或 5.7 的安装版。8.0 的安装向导比较直观但在设置认证方式那一步建议选 Use Legacy Authentication这样可以兼容老驱动。如果选了默认的 caching_sha2_password旧版mysql-connector-java驱动会连不上报认证插件错误。配套用 8.0 的驱动和 8.0 的数据库认证协议一致省心很多。安装完成后打开 MySQL 8.0 Command Line Client输入密码能进入mysql提示符就算装好了。如果没有命令行入口就用 Windows 服务方式启动打开服务管理器确认 MySQL 服务在运行或者命令行执行net start mysql。这里有个小坑如果你下载的是免安装压缩版比如mysql-8.0.x-winx64需要手动初始化 data 目录和 root 密码。步骤是解压后在目录下执行mysqld --initialize-insecure然后mysqld --install注册服务再net start mysql。初始化成功后 root 没有密码登录后要立刻修改不然数据库裸奔。建库时字符集要一步到位CREATE DATABASE student_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;逻辑说明utf8mb4 是 MySQL 8.0 推荐使用的字符集支持中文和 emoji比老的 utf8 更完整。建库时指定字符集后续所有表默认继承这个设置避免建表时遗漏。collate 选 general_ci 即可排序规则不区分大小写适合学生信息这种场景。参数说明collate 后面对应的是排序规则utf8mb4_general_ci性能好utf8mb4_unicode_ci对多语言排序更准确。课设用 general_ci 就够。这个选择直接决定后续SELECT按中文姓名排序时的表现如果排序结果看着不对劲先检查 collate 配置。很多同学把代码和数据配好了唯独忘了先执行这条建库语句或者建了库但没设置字符集导致输入中文后界面显示问号。这类问题在答辩时经常被老师当场指出来。2.3 驱动 JAR 与项目骨架eclipse 里构建路径的三步操作JDBC 驱动是 Java 应用和 MySQL 之间的桥梁。下载mysql-connector-j的 JAR 包放到项目根目录下新建的lib文件夹。然后在 eclipse 里选中 JAR右键 → Build Path → Add to Build Path。这一步不做的后果就是运行时抛ClassNotFoundException代码写再多也白搭。项目骨架方面我习惯按下面这种方式分包src ├── view Swing 界面类 ├── dao 数据访问类 ├── entity 实体类 ├── util 公共工具类 └── resources db.properties 配置这种分包方式的好处是答辩时老师问“分层在哪”不会哑口无言。学生信息管理系统的功能不算大但分成界面、数据访问、实体工具三层后代码的可读性明显上升后续加功能也不用把整个类重写。从网上下载的源码包很多是几十个类平铺在 src 下界面代码和数据库代码混在一起当然也能跑但答辩现场很难讲清楚。有耐心的话把类按这个结构归置收益很高。3. 数据库与连接层建表 SQL、JDBC 工具类、实体映射一次到位3.1 建表 SQL学生表、用户表、成绩表怎么设计字段学生信息管理系统绕不开三张表用户表登录验证、学生表核心数据、成绩表扩展功能。设计时建议学生表和成绩表通过学号关联而不是用自增主键关联因为学号本身是业务主键天然唯一。CREATE TABLE tb_admin ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(30) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE tb_student ( stu_id VARCHAR(20) PRIMARY KEY, stu_name VARCHAR(50) NOT NULL, gender CHAR(2) DEFAULT 男, major VARCHAR(50), class_name VARCHAR(50), phone VARCHAR(15), create_time DATETIME DEFAULT CURRENT_TIMESTAMP ) ENGINEInnoDB DEFAULT CHARSETutf8mb4; CREATE TABLE tb_score ( score_id INT PRIMARY KEY AUTO_INCREMENT, stu_id VARCHAR(20) NOT NULL, course_name VARCHAR(50) NOT NULL, score DECIMAL(5,2), CONSTRAINT fk_stu_score FOREIGN KEY (stu_id) REFERENCES tb_student(stu_id) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;逻辑说明tb_admin 里 username 加 UNIQUE 约束防止系统出现重复账号password 字段用 VARCHAR(64)为的是以后可以存加密结果而不是明文。tb_student 用 stu_id 做主键学生管理场景里学号本身就是唯一业务标识用自增 INT 主键反而要维护多一个映射关系。create_time 字段带 DEFAULT CURRENT_TIMESTAMP插入时不用手动填时间。参数说明score 字段用 DECIMAL(5,2)表示最高 999.99 分同时保留两位小数gender 用 CHAR(2) 而不是 VARCHAR定长字符串在 InnoDB 下更省空间。外键 fk_stu_score 的作用是防止成绩表出现不存在的学生。删学生时如果成绩表还有记录数据库会拒绝删除这是双刃剑后面的避坑章节会细讲。初始化时记得插入一条管理员数据INSERT INTO tb_admin(username, password) VALUES (admin, 123456);没有这条数据登录功能一定报错或者永远验证失败。密码先用明文占位最后讲怎么改成加密存储。3.2 JDBC 连接工具类配置文件加单例 Connection 的写法连接数据库的代码不应该散落在每个 DAO 里否则改一次密码要改五六处。常见做法是写一个 JdbcUtils 工具类URL、用户名、密码全放在db.properties配置文件中由工具类读取jdbc.drivercom.mysql.cj.jdbc.Driver jdbc.urljdbc:mysql://localhost:3306/student_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8 jdbc.usernameroot jdbc.password123456package util; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; public class JdbcUtils { private static String driver; private static String url; private static String username; private static String password; static { try { InputStream in JdbcUtils.class.getClassLoader() .getResourceAsStream(db.properties); Properties props new Properties(); props.load(in); driver props.getProperty(jdbc.driver); url props.getProperty(jdbc.url); username props.getProperty(jdbc.username); password props.getProperty(jdbc.password); Class.forName(driver); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } public static void close(Connection conn, Statement st, ResultSet rs) { if (rs ! null) { try { rs.close(); } catch (SQLException ignored) {} } if (st ! null) { try { st.close(); } catch (SQLException ignored) {} } if (conn ! null) { try { conn.close(); } catch (SQLException ignored) {} } } }逻辑说明static 块在类加载时执行一次读取配置并加载驱动。Class.forName(driver) 这行在 JDBC 4.0 之后可以省略但保留它对老版本更稳妥。getResourceAsStream 从 classpath 加载资源所以 db.properties 要放在 src 根目录下eclipse 默认会把 src 下的文件复制到输出目录。参数说明serverTimezoneAsia/Shanghai 是 MySQL 8.0 的必填参数不写会报时区异常useSSLfalse 是为了避免本地调试时 SSL 握手告警刷屏。characterEncodingutf8 解决中文字符编码问题和数据库端的 utf8mb4 设置配套使用。这三项缺一个都会在运行时出现莫名其妙的现象。3.3 实体类与 DAOResultSet 转对象的标准套路实体类的字段照数据库表结构抄一遍即可注意使用包装类型而不是基本类型。比如成绩用 BigDecimal 对应 DECIMAL 字段不要用 double避免精度丢失package entity; import java.time.LocalDateTime; public class Student { private String stuId; private String stuName; private String gender; private String major; private String className; private String phone; private LocalDateTime createTime; public Student() {} public Student(String stuId, String stuName, String gender, String major, String className, String phone) { this.stuId stuId; this.stuName stuName; this.gender gender; this.major major; this.className className; this.phone phone; } // getter/setter 用 eclipse 的 AltShiftS 一键生成 }DAO 层的核心方法是增删改查查询全部学生是一个高频操作package dao; import entity.Student; import util.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; public class StudentDao { public ListStudent queryAll() { String sql SELECT stu_id, stu_name, gender, major, class_name, phone FROM tb_student; ListStudent list new ArrayList(); try (Connection conn JdbcUtils.getConnection(); PreparedStatement ps conn.prepareStatement(sql); ResultSet rs ps.executeQuery()) { while (rs.next()) { Student s new Student(); s.setStuId(rs.getString(stu_id)); s.setStuName(rs.getString(stu_name)); s.setGender(rs.getString(gender)); s.setMajor(rs.getString(major)); s.setClassName(rs.getString(class_name)); s.setPhone(rs.getString(phone)); list.add(s); } } catch (Exception e) { e.printStackTrace(); } return list; } }逻辑说明这里用了 try-with-resources是 Java 7 之后的特性Connection、PreparedStatement、ResultSet 都实现了 AutoCloseable方法结束自动关闭不用手动调用 close。SQL 里只查了界面上展示的六个字段没有查 create_time减少不必要的数据传递。参数说明rs.getString 按列名取值前提是 SQL 里 select 出来的列名和实体类字段名能对上。如果数据库字段含下划线比如 class_nameJAVA 里映射为 className要靠 setter 手工转换或者用 MyBatis 这类框架的 mapUnderscoreToCamelCase 自动映射。课设阶段手写 setter 更直观也方便答辩时讲清楚数据流转。4. 功能实现与界面联动登录校验、增删改查、JTable 刷新的完整闭环4.1 登录校验PreparedStatement 参数化查询防注入登录模块看起来简单实际很有讲究。最常见的错误做法是字符串拼接 SQLString sql SELECT * FROM tb_admin WHERE username username AND password password ;这种写法在课程设计里能跑但一旦用户名输入 OR 11就可以绕过登录。学生系统虽然不会成为攻击目标但养成写 PreparedStatement 的习惯是必要的public boolean login(String username, String password) { String sql SELECT COUNT(*) FROM tb_admin WHERE username ? AND password ?; try (Connection conn JdbcUtils.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, password); try (ResultSet rs ps.executeQuery()) { rs.next(); return rs.getInt(1) 0; } } catch (Exception e) { e.printStackTrace(); return false; } }逻辑说明使用 ? 占位符通过 setString 设置参数PreparedStatement 会转义单引号等特殊字符从根源上解决 SQL 注入。用 SELECT COUNT(*) 而不是 SELECT *查询结果只需要判断是否存在减少了数据传输量。rs.getInt(1) 取的是第一条记录的第一个字段也就是 COUNT 的结果大于 0 说明账号密码匹配。参数说明登录成功后Swing 桌面应用没有 HttpSession可以在一个 AppContext 静态变量里保存当前登录用户后续做操作权限判断时直接取用。4.2 学生信息的增删改查完整 DAO 写法核心功能是增删改查这里给出 addStudent、updateStudent、deleteStudent 三个方法public boolean addStudent(Student s) { String sql INSERT INTO tb_student(stu_id, stu_name, gender, major, class_name, phone) VALUES(?,?,?,?,?,?); try (Connection conn JdbcUtils.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, s.getStuId()); ps.setString(2, s.getStuName()); ps.setString(3, s.getGender()); ps.setString(4, s.getMajor()); ps.setString(5, s.getClassName()); ps.setString(6, s.getPhone()); return ps.executeUpdate() 1; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean updateStudent(Student s) { String sql UPDATE tb_student SET stu_name?, gender?, major?, class_name?, phone? WHERE stu_id?; try (Connection conn JdbcUtils.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, s.getStuName()); ps.setString(2, s.getGender()); ps.setString(3, s.getMajor()); ps.setString(4, s.getClassName()); ps.setString(5, s.getPhone()); ps.setString(6, s.getStuId()); return ps.executeUpdate() 1; } catch (Exception e) { e.printStackTrace(); return false; } } public boolean deleteStudent(String stuId) { String sql DELETE FROM tb_student WHERE stu_id?; try (Connection conn JdbcUtils.getConnection(); PreparedStatement ps conn.prepareStatement(sql)) { ps.setString(1, stuId); return ps.executeUpdate() 1; } catch (Exception e) { e.printStackTrace(); return false; } }逻辑说明注意 update 语句的参数顺序第一个 ? 对应 stu_name最后一个 ? 对应 WHERE 里的 stu_id必须和 setString 的调用顺序一一对应这是新手最容易写错的地方。executeUpdate 返回受影响的行数等于 1 说明操作生效返回 0 说明传入的实体对象数据有问题比如主键不存在。参数说明deleteStudent 只接收 stuId 字符串界面层点击“删除”时先拿到 JTable 选中行的学号再调用这个方法。删除前要有确认提示防止误操作。如果成绩表有外键关联删除会受到约束后面避坑章节会细说。4.3 Swing 界面JTable 刷新与事件绑定的写法Swing 界面代码冗长但逻辑直接。典型主界面是一张 JTable 加增删改查四个按钮。核心难点只有一个操作完成后表格怎么立即刷新。常规做法是封装一个 loadTableData 方法private void loadTableData() { ListStudent list new StudentDao().queryAll(); DefaultTableModel model (DefaultTableModel) table.getModel(); model.setRowCount(0); for (Student s : list) { model.addRow(new Object[]{ s.getStuId(), s.getStuName(), s.getGender(), s.getMajor(), s.getClassName(), s.getPhone() }); } }按钮“添加”的点击事件写法btnAdd.addActionListener(e - { String stuId txtStuId.getText().trim(); String stuName txtStuName.getText().trim(); String gender (String) cmbGender.getSelectedItem(); String major txtMajor.getText().trim(); String className txtClassName.getText().trim(); String phone txtPhone.getText().trim(); if (stuId.isEmpty() || stuName.isEmpty()) { JOptionPane.showMessageDialog(this, 学号和姓名不能为空); return; } Student s new Student(stuId, stuName, gender, major, className, phone); boolean ok new StudentDao().addStudent(s); if (ok) { JOptionPane.showMessageDialog(this, 添加成功); loadTableData(); clearInput(); } else { JOptionPane.showMessageDialog(this, 添加失败请检查学号是否重复); } });逻辑说明addActionListener 里先用 getText().trim() 取输入框内容并去掉首尾空格学号和姓名做非空校验由界面层拦截无效数据比等数据库报错更友好。添加成功后必须调用 loadTableData() 刷新表格这是很多项目“新增后记录不消失”的根源——忘了刷新表格模型。参数说明DefaultTableModel 的 setRowCount(0) 等价于清空所有行之后 addRow 追加新数据。JTable 要设置单选模式 setSelectionMode(ListSelectionModel.SINGLE_SELECTION)否则用户按住 CTRL 能选多行后续取当前选中学号时逻辑会混乱。取当前行学号的写法是table.getValueAt(table.getSelectedRow(), 0).toString()。5. 避坑与排查五个最常见的运行时问题及处理办法5.1 java.lang.ClassNotFoundException现象运行登录模块时控制台报 ClassNotFoundException指向 Class.forName 或第一次 new 驱动的那一行。原因驱动 JAR 没有加入构建路径。mysql-connector 的 JAR 文件没有被 eclipse 编译到 classpath或者 JAR 根本没下载到 lib 目录。解决先确认项目根目录 lib 下有 mysql-connector 的 JAR 包没有就去下载对应的版本放入然后右键项目 → Build Path → Configure Build Path → Add JARs把 JAR 添加进去。添加成功后Project Explorer 里 JAR 文件左侧会显示可展开的三角箭头没有箭头说明没有被识别为库文件。5.2 Communications link failure 连接失败现象运行时提示 Communications link failure有时还带 Connection refused 或 Access denied for user 字样。原因MySQL 服务没启动或者用户名密码和配置文件里的不一致。很多同学安装时设置了自定义密码但代码里写的是初始的 root 空密码或者 123456。另一个隐藏原因是 MySQL 8.0 安装时选了非默认端口比如 3307。解决WinR 输入 services.msc确认 MySQL 服务状态是 running或者命令行执行net start mysql。如果服务正常但还连不上把连接地址从localhost改成127.0.0.1再试因为 localhost 有时会解析到 IPv6 导致连接失败。URL 写法jdbc:mysql://127.0.0.1:3306/student_db?useSSLfalseserverTimezoneAsia/ShanghaicharacterEncodingutf8。5.3 中文乱码问题现象界面上输入中文正常但数据库里是问号或者从数据库读出来的中文在界面上显示为乱码。原因数据库字符集和连接串编码不一致。常见有三处出错数据库建库时用的默认字符集不是 utf8mb4连接串里没加 characterEncodingutf8eclipse 工作空间的文本编码不是 UTF-8导致 Java 源码文件本身以 GBK 保存。解决三步统一定位。第一步在 MySQL 命令行执行SHOW CREATE DATABASE student_db;确认字符集是 utf8mb4第二步检查 db.properties 里连接串是否带 characterEncodingutf8第三步确认 eclipse 的 Window → Preferences → Workspace → Text file encoding 为 UTF-8。三处统一后中文乱码基本可以根治。5.4 eclipse 导入项目后大量红叉现象导入下载的源码包后项目名上没有 Java 图标或者源码文件大量报错错位 com.mysql.jdbc.Driver 和 javax.swing 都找不到。原因源码包解压后缺省.project和.classpath文件eclipse 把它当普通文件夹导入了即使导成 Java 项目类路径里没有 JRE System Library 和驱动 JAR自然一片红叉。解决右键项目 → Configure → Convert to Faceted Form或者 Project Properties → Project Facets 勾选 Java然后右键项目 → Build Path → Add Library → JRE System Library再按第 2.3 节的方式导入驱动 JAR。如果编译缓存损坏最后执行 Project → Clean 重建项目。5.5 删除学生报外键约束失败现象删除学生时界面弹“删除失败”控制台报 Cannot delete or update a parent row: a foreign key constraint fails。原因tb_score 表通过外键引用了这个学号数据库为了保持引用完整性拒绝删除。这是数据库的防呆设计阻止你悄悄丢掉学生成绩记录。解决按业务决定处理策略。推荐在删除学生前先删除成绩记录把两个删除操作放在一个事务里执行public boolean deleteStudentWithScore(String stuId) { Connection conn null; try { conn JdbcUtils.getConnection(); conn.setAutoCommit(false); try (PreparedStatement ps1 conn.prepareStatement(DELETE FROM tb_score WHERE stu_id?); PreparedStatement ps2 conn.prepareStatement(DELETE FROM tb_student WHERE stu_id?)) { ps1.setString(1, stuId); ps1.executeUpdate(); ps2.setString(1, stuId); ps2.executeUpdate(); conn.commit(); return true; } catch (Exception e) { conn.rollback(); e.printStackTrace(); return false; } } catch (Exception e) { e.printStackTrace(); return false; } finally { try { if (conn ! null) conn.close(); } catch (Exception ignored) {} } }逻辑说明setAutoCommit(false) 开启手动事务两个 delete 都成功后统一 commit中间任一操作失败就 rollback保证不会出现“学生删了成绩残留”的脏数据。这样一个看似简单的删除操作就能在答辩时多讲出一个“事务处理”的亮点。如果想省事也可以把外键改成 ON DELETE CASCADE 让数据库自动级联但这样误删成本太高新手不建议。6. 答辩前的验证与增强用一张清单和三个技巧收尾6.1 交付前按这份清单过一遍代码写完不是终点跑一遍下面的测试记录才算真的交付测试项操作方式预期结果登录校验输入 admin / 123456成功进入主界面错误密码输入任意错误密码弹窗提示登录失败添加学生填写完整信息表格立即刷新出现新记录重复学号添加已存在的学号弹窗提示添加失败修改信息选中一行改动后保存表格数据更新删除学生选中带成绩的学生删除弹窗提示删除失败或联动删除中文显示输入中文姓名和专业界面与数据库均无乱码这份清单覆盖了登录、增删改查、异常分支和编码答辩演示时按这个顺序走基本不会出岔子。6.2 三个低成本增强密码加密、分页查询、导出 CSV第一个增强是密码加密。明文密码在数据库里是硬伤至少改成 MD5 或 SHA-256 加盐存储。登录时把用户输入的值加密后再拼 SQL 查询条件改动量不大但答辩观感完全不同。第二个增强是分页查询。学生数据超过几十条后一次性查完既慢又不专业。在 DAO 的查询方法里加两个参数 pageIndex 和 pageSizeSQL 末尾追加LIMIT ? OFFSET ?界面上放上一页、下一页按钮即可。这个改动对 JTable 刷新逻辑的冲击很小性价比很高。第三个增强是导出 CSV。用一个 JFileChooser 选择保存路径把表格数据按 CSV 格式拼接成字符串写入文件。CSV 文件可以直接用 Excel 打开功能演示时效果很好而且实现代码只有几十行。这三个增强点做完从一个只能增删改查的演示程序变成有工程意识的系统答辩老师那边给分逻辑完全不同。从那以后我每次交付 Java 课设项目都强制走一遍那份验收清单再去交代码代码结构和记录验证并行从源头上避开大大小小的坑。希望帮到你。本文还有配套的精品资源点击获取
返回列表