☰
学生宿舍管理系统课程设计:MySQL+Java+Swing全栈实现详解
2026/9/26 4:34:51 网站建设 项目流程

简介:面向计算机相关专业课程设计需求,这份基于MySQL+Java Swing开发的学生宿舍管理系统完整项目包,适合需要完成数据库课程设计或练习桌面端管理系统的学习者。项目覆盖管理员、学生、宿舍管理等核心功能,采用分层设计将界面、业务逻辑与数据访问分离,并配有图表与说明文档,可帮助快速理清业务流程与界面交互逻辑。包体共334个文件,主要包含47个Java源文件、202个class编译文件、22张PNG界面截图,以及XML配置、数据库脚本、jar依赖等,压缩包约112.72MB,结构完整,便于导入开发环境并直接运行。已有268人学习下载,适合参考总体架构、复用业务代码或作为课程答辩展示。通过源码与图表可以掌握Swing桌面界面构建、MySQL表结构设计以及JDBC数据库连接等关键知识点,是一份能切实支撑课程设计报告与代码实现的完整素材。

1. 学生宿舍管理系统课程设计:MySQL+Java+Swing 三件套为什么是稳妥答案

mysql课程设计 这个题目每年都在课程设计题库里出现,学生宿舍管理系统则是最常见的载体。用 MySQL 存数据、Java 写业务逻辑、Swing 搭桌面界面,这个组合的好处是不依赖任何 Web 容器,一个 main 方法就能启动,还能把数据库设计、JDBC、集合框架、事件监听、SQL 聚合这些 java 基础考点全部串进一个项目里。比起纯控制台版本,带 Swing 图形界面和图表统计的版本在答辩时明显更占优势——演示路径从输入账号密码开始,到点击按钮生成图表结束,整个过程是可视的。如果你正在找课程设计案例源码做参考,或者想把 Java 基础从头到尾串一遍,这套方案可以直接照着搭。

2. 从需求到建表:宿舍管理系统的数据模型设计与 DDL 落地

2.1 学生宿舍的业务对象拆解:先画关系再写代码

做课程设计最容易翻车的地方不是写代码,而是拿到题目就建表。宿舍管理系统看上去简单,但「学生和宿舍」之间的关系并不是一个 student 表加一个 dorm 表就能说清楚。学生要入住宿舍,入住有日期、有床位号,之后会产生水电费账单,账单可能是每月一条。如果把入住信息直接塞进 student 表,后续统计「当前住在 3 号楼的人数」就要去查学生表里一个可空的宿舍字段,SQL 写起来别扭,外键也不好维护。

我一般会先把业务对象画出来:管理员(admin)负责登录和后台维护;宿舍楼(dormitory)包含楼号、楼层、房间号、床位总数;学生(student)保存学号、姓名、性别、联系方式这些基础信息;入住记录(checkin)把学生和宿舍关联起来,记录入住时间和床位;水电费(fee)按宿舍或按入住记录生成账单,记录用量、金额和缴费状态。这五个对象之间的关系足够支撑课程设计的功能演示,也不会把表拆得太多导致工作量失控。

画完关系再写代码,后面每一个 DAO 方法都能找到对应的表,答辩时老师问「这个字段为什么这样设计」也能直接说出理由。本地 MySQL 装好之后,建议先用命令行mysql -u root -p登录确认密码和端口没问题,再执行下面的建库脚本。

2.2 建库建表 DDL:五张核心表与字段约束设计

建库第一步是先确定字符集。课程设计用的电脑上 MySQL 版本不太一致,有的还是 5.7,有的是 8.0,字符集统一用 utf8mb4 最省事。建库时直接指定,避免后面插入中文出现 data too long 或者乱码。

CREATE DATABASE dorm_manage DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; USE dorm_manage; CREATE TABLE admin ( id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32) NOT NULL UNIQUE, password VARCHAR(64) NOT NULL, real_name VARCHAR(32), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB; CREATE TABLE dormitory ( id INT PRIMARY KEY AUTO_INCREMENT, building_no VARCHAR(16) NOT NULL, room_no VARCHAR(16) NOT NULL, bed_count INT NOT NULL, used_bed INT DEFAULT 0, floor_no INT, UNIQUE KEY uk_building_room (building_no, room_no) ) ENGINE=InnoDB; CREATE TABLE student ( id INT PRIMARY KEY AUTO_INCREMENT, student_no VARCHAR(20) NOT NULL UNIQUE, name VARCHAR(32) NOT NULL, gender CHAR(1) COMMENT 'F-女 M-男', phone VARCHAR(11), major VARCHAR(64), enrolled_year INT, dorm_id INT, bed_no VARCHAR(8), CONSTRAINT fk_student_dorm FOREIGN KEY (dorm_id) REFERENCES dormitory(id) ) ENGINE=InnoDB; CREATE TABLE checkin ( id INT PRIMARY KEY AUTO_INCREMENT, student_id INT NOT NULL, dorm_id INT NOT NULL, checkin_date DATE NOT NULL, checkout_date DATE, bed_no VARCHAR(8), status TINYINT DEFAULT 1 COMMENT '1-在住 0-已退宿', CONSTRAINT fk_checkin_student FOREIGN KEY (student_id) REFERENCES student(id), CONSTRAINT fk_checkin_dorm FOREIGN KEY (dorm_id) REFERENCES dormitory(id) ) ENGINE=InnoDB; CREATE TABLE fee ( id INT PRIMARY KEY AUTO_INCREMENT, dorm_id INT NOT NULL, student_id INT NOT NULL, fee_type VARCHAR(16) COMMENT 'water/electric', amount DECIMAL(8,2) NOT NULL, record_month CHAR(7) NOT NULL, is_paid TINYINT DEFAULT 0, paid_date DATE, CONSTRAINT fk_fee_dorm FOREIGN KEY (dorm_id) REFERENCES dormitory(id), CONSTRAINT fk_fee_student FOREIGN KEY (student_id) REFERENCES student(id) ) ENGINE=InnoDB;

这段 DDL 有几个地方是答辩时的加分点。admin 表里 password 字段长度设成 64,是因为密码会用 SHA-256 处理后再落库,不要图省事存明文。dormitory 表加了 uk_building_room 唯一索引,防止同一栋楼的同一个房间被重复插入。student 表和 checkin 表都保留 dorm_id 和 bed_no,是因为有的学校要求「先分配宿舍后办理入住」,有的要求「入住时再登记床位」,两张表各存一份能兼容两种流程。

fee 表用 record_month 保存账单月份,格式是 2025-01 这种,方便用字符串比较做月度筛选。amount 用 DECIMAL(8,2) 而不是 FLOAT,是为了避免浮点误差导致对不上账——这是被实际账单数据坑过才会注意的地方。用 MySQL Workbench 执行这段脚本也可以,但命令行执行更能看清每一条报错。

2.3 初始化数据:管理员账号与测试学生的插入脚本

建完表之后要准备初始化数据,不然系统启动后界面是空的,演示效果很差。初始化脚本里至少要有:一个管理员账号,三到四栋宿舍楼,每栋楼若干房间,以及十几条学生记录。

INSERT INTO admin (username, password, real_name) VALUES ('admin', SHA2('123456', 256), '系统管理员'); INSERT INTO dormitory (building_no, room_no, bed_count, used_bed, floor_no) VALUES ('1号楼', '101', 4, 3, 1), ('1号楼', '102', 4, 4, 1), ('2号楼', '201', 6, 5, 2), ('2号楼', '202', 6, 2, 2); INSERT INTO student (student_no, name, gender, phone, major, enrolled_year, dorm_id, bed_no) VALUES ('20230101', '张伟', 'M', '13800138001', '计算机科学与技术', 2023, 1, 'A床'), ('20230102', '李娜', 'F', '13800138002', '软件工程', 2023, 3, 'A床'), ('20230103', '王强', 'M', '13800138003', '计算机科学与技术', 2023, 1, 'B床'); INSERT INTO checkin (student_id, dorm_id, checkin_date, status) VALUES (1, 1, '2023-09-01', 1), (2, 3, '2023-09-01', 1), (3, 1, '2023-09-01', 1); INSERT INTO fee (dorm_id, student_id, fee_type, amount, record_month, is_paid) VALUES (1, 1, 'electric', 85.50, '2025-01', 1), (1, 3, 'electric', 92.00, '2025-01', 0), (3, 2, 'water', 23.40, '2025-01', 1);

注意 student 表和 checkin 表里的 dorm_id 要保持一致,否则后面关联查询会查出对不上的数据。SHA2('123456', 256) 是 MySQL 自带的哈希函数,Java 端登录验证时用 SHA-256 把用户输入的密码哈希后再和库里的值比对,两边算法对齐才能通过。

3. Swing 界面 + JDBC 数据库访问:项目骨架与登录模块的实现路径

3.1 项目分包与启动入口:entity/dao/service/view 四层怎么分

课程设计项目虽然不大,但不要把所有类都丢在默认包底下。常见的做法是分成四个包:entity 放实体类,对应数据库里的每张表;dao 放数据库访问类,每个实体一个 DAO;service 放业务逻辑,比如登录校验、入住分配;view 放 Swing 界面类。再单独放一个 util 包,装 JDBC 工具类和常量类。

src ├── com.dorm.entity │ ├── Admin.java │ ├── Student.java │ ├── Dormitory.java │ ├── Checkin.java │ └── Fee.java ├── com.dorm.dao │ ├── AdminDao.java │ ├── StudentDao.java │ ├── DormitoryDao.java │ ├── CheckinDao.java │ └── FeeDao.java ├── com.dorm.service │ ├── LoginService.java │ └── StatService.java ├── com.dorm.view │ ├── LoginFrame.java │ ├── MainFrame.java │ └── StatPanel.java └── com.dorm.util ├── DBUtil.java └── Constants.java

分层的理由是让每个类的职责单一。LoginFrame 只负责收集用户名和密码并调用 service,至于怎么查库、怎么比对哈希,都在 LoginService 和 AdminDao 里完成。这样答辩时老师如果要你现场改一个功能,改动范围是可控的——比如把密码从 SHA-256 换成 MD5,只改 service 里的一行。

启动入口写一个 Main.java,放在 com.dorm 包下,只做一件事:设置 Swing 外观,然后打开 LoginFrame。这个入口类的名字没有强制要求,但建议就叫 Main,因为打包时指定主类最直观。

3.2 JDBC 工具类与连接参数:驱动、URL、时区一个都不能少

MySQL 的 JDBC 驱动和连接 URL 是课程设计里最常见的翻车点。MySQL 5.7 和 8.0 的驱动都在 mysql-connector-java 包里,但 URL 参数有差异。8.0 版本要求明确时区,否则会报错,而且 8.0 默认的 caching_sha2_password 认证插件也要求客户端支持,否则报 Public Key Retrieval is not allowed。

public class DBUtil { private static final String DRIVER = "com.mysql.cj.jdbc.Driver"; private static final String URL = "jdbc:mysql://localhost:3306/dorm_manage" + "?useUnicode=true&characterEncoding=utf8" + "&useSSL=false&serverTimezone=Asia/Shanghai" + "&allowPublicKeyRetrieval=true"; private static final String USER = "root"; private static final String PASSWORD = "123456"; static { try { Class.forName(DRIVER); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } public static void close(Connection conn, PreparedStatement ps, ResultSet rs) { try { if (rs != null) rs.close(); } catch (SQLException ignored) {} try { if (ps != null) ps.close(); } catch (SQLException ignored) {} try { if (conn != null) conn.close(); } catch (SQLException ignored) {} } }

这段把 URL 拆成几段解释一下。useUnicode=true 和 characterEncoding=utf8 是给 MySQL 5.7 时代的习惯性配置,8.0 里同样有效,作用是让中文数据在传输过程中不乱码。serverTimezone=Asia/Shanghai 解决 8.0 驱动必须指定时区的问题,不写的话直接报 The server time zone value is unrecognized。allowPublicKeyRetrieval=true 解决 caching_sha2_password 认证时客户端无法自动获取公钥的问题,这个参数不加,连接阶段就会抛异常。USER 和 PASSWORD 先写死在工具类里,等打包交付前再抽到 db.properties。

3.3 登录模块:JFrame 事件监听到 PreparedStatement 的完整链路

登录界面是系统给评委的第一印象,不要求花哨,但布局要整齐。用 JFrame + GridBagLayout 或者最简单的绝对布局都能接受,关键是登录按钮的监听器里要完成「取输入 → 调 service → 按结果跳转」这条完整链路。

public class LoginFrame extends JFrame { private JTextField userField; private JPasswordField pwdField; public LoginFrame() { setTitle("学生宿舍管理系统 - 登录"); setSize(420, 280); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); // 布局代码省略:中间放用户名输入框、密码输入框,底部放登录按钮 loginBtn.addActionListener(e -> doLogin()); } private void doLogin() { String username = userField.getText().trim(); String password = new String(pwdField.getPassword()); if (username.isEmpty() || password.isEmpty()) { JOptionPane.showMessageDialog(this, "用户名和密码不能为空"); return; } boolean ok = new LoginService().checkLogin(username, password); if (ok) { dispose(); new MainFrame().setVisible(true); } else { JOptionPane.showMessageDialog(this, "用户名或密码错误"); } } }

使用 JPasswordField 而不是 JTextField,是因为密码框不会明文显示输入内容,getPassword() 返回 char 数组,new String 转成字符串再参与哈希计算。注意不要调用 getText() 从密码框取输入,Swing 不推荐这种做法,原因也是安全上的考虑。

LoginService 里的 checkLogin 方法负责生成 SHA-256 哈希并调用 DAO 查询,DAO 层用 PreparedStatement 而不是 Statement,是为了杜绝拼接 SQL 的注入风险,同时也是课程设计评分里的一个加分点。

public boolean checkLogin(String username, String password) { String hash = SHA256Util.hash(password); String sql = "SELECT id FROM admin WHERE username = ? AND password = ?"; try (Connection conn = DBUtil.getConnection(); PreparedStatement ps = conn.prepareStatement(sql)) { ps.setString(1, username); ps.setString(2, hash); try (ResultSet rs = ps.executeQuery()) { return rs.next(); } } catch (SQLException e) { e.printStackTrace(); return false; } }

try-with-resources 会自动关闭连接,这是 Java 7 之后的特性,课程设计里用上它比手动在 finally 里关连接更简洁,也能避免资源泄漏。SHA256Util 就是通过 MessageDigest 计算哈希并把字节数组转成十六进制字符串的工具类,注意输出格式和 MySQL 的 SHA2() 要保持一致,否则登录永远比对不上。

4. 从 SQL 聚合到 JFreeChart:宿舍入住率与水电费图表统计实现

4.1 图表数据来源:用 GROUP BY 聚合查询生成数据集

图表不是无中生有的,它的数据源一定是一条 SQL 聚合语句。比如统计各宿舍楼入住人数,先按 building_no 分组,再关联 student 表统计 dorm_id 非空的人数。做这一步之前,先想清楚图表要回答什么问题——入住率、各楼缴费情况、男女比例,每个问题对应一条单独的统计 SQL。

SELECT d.building_no, COUNT(s.id) AS student_count FROM dormitory d LEFT JOIN student s ON s.dorm_id = d.id GROUP BY d.building_no, d.id; SELECT dorm_id, SUM(CASE WHEN fee_type='electric' THEN amount ELSE 0 END) AS elec_total, SUM(CASE WHEN fee_type='water' THEN amount ELSE 0 END) AS water_total FROM fee WHERE record_month = '2025-01' GROUP BY dorm_id;

这两条 SQL 的特点是有条件聚合,CASE WHEN 可以把同一张表里的水电费拆成两列,避免了分别查两次再在 Java 里拼数据。在 DAO 层封装时,用 List 接收结果,StatItem 就两个字段 label 和 value,加 getter/setter,这样 JFreeChart 直接遍历列表就能构造数据集。

4.2 JFreeChart 接入:柱状图与饼图的最小实现

JFreeChart 是 Java Swing 生态里常用的图表库,课程设计里用它画柱状图和饼图足够。引入方式是把 jfreechart-1.5.3.jar 放到项目的 lib 目录并加入 classpath。核心代码就三件事:构造数据集、创建 Chart 对象、把 Chart 显示到 JPanel 上。

public JPanel createBarChart(List<StatItem> items) { DefaultCategoryDataset dataset = new DefaultCategoryDataset(); for (StatItem item : items) { dataset.addValue(item.getValue(), "入住人数", item.getLabel()); } JFreeChart chart = ChartFactory.createBarChart( "各宿舍楼入住人数统计", // 图表标题 "宿舍楼", // X 轴标签 "人数", // Y 轴标签 dataset, // 数据 PlotOrientation.VERTICAL, true, // 显示图例 true, // 显示 tooltip false // 不生成 URL ); ChartPanel panel = new ChartPanel(chart); panel.setPreferredSize(new Dimension(560, 320)); return panel; }

ChartFactory.createBarChart 有 8 个参数,前四个决定数据展示,后三个是图例、tooltip 和 URL 的开关。课程设计界面里图例可以开,tooltip 开着能在鼠标悬停时看到数值,答辩演示时很直观。URL 参数对桌面应用没有意义,置为 false 即可。饼图用 createPieChart,参数更少,数据源用 DefaultPieDataset,用法几乎一样,照着柱状图改就能出。

4.3 图表导出与报表整合:保存 PNG 后嵌入 Word 文档

图表除了在界面上显示,课程设计要求里通常还有「图表要能出现在文档里」这项。JFreeChart 自带 ChartUtils.saveChartAsPNG,一行代码就能把图表存成本地图片。存完之后可以使用 Apache POI 把图片插进 Word 文档,也可以用最笨的办法——把 PNG 截图贴进课程设计报告里。

File outFile = new File("dorm_stat_" + System.currentTimeMillis() + ".png"); ChartUtils.saveChartAsPNG(outFile, chart, 560, 320); BufferedImage image = ChartUtils.readBufferedImage(outFile); JLabel imageLabel = new JLabel(new ImageIcon(image)); imageLabel.setHorizontalAlignment(JLabel.CENTER);

saveChartAsPNG 的三个参数是文件对象、Chart 对象和图片宽高。保存前要注意目录是否存在,直接写相对路径时,文件会生成在项目运行目录下,如果用 IDEA 运行,可能在项目根目录,而不是 src 下。有的同学点了导出按钮找不到图片,多半就是没注意当前工作目录。

用 POI 嵌入 Word 的代码稍微长一些,但逻辑固定:新建 XWPFDocument,调用 createParagraph 创建段落,再由 paragraph 的 run 对象调用 addPicture 把图片字节流写入文档。注意 addPicture 需要指定图片类型常量 Document.PICTURE_TYPE_PNG,否则会抛 IllegalArgumentException。

提示:JFreeChart 的图表标题和坐标轴标签也受本地字体影响,如果导出到其他机器上显示成方块,在创建 Chart 后设置 cn.something 的字体替换,或者直接在 JVM 启动参数里指定-Dfile.encoding=UTF-8。

5. 课程设计避坑指南:MySQL 与 Swing 集成的 5 个典型翻车点

5.1 MySQL 8.0 连接失败:Public Key Retrieval 与时区两个拦路虎

现象:程序启动后第一个数据库操作就抛异常,要么是 SQLNonTransientConnectionException: Public Key Retrieval is not allowed,要么是 The server time zone value is unrecognized。

原因:MySQL 8.0 默认的认证插件是 caching_sha2_password,客户端首次连接需要从服务器获取公钥,而 JDBC 驱动出于安全考虑默认不自动获取;时区错误则是 8.0 驱动要求客户端和服务端时区一致,连接串里没显式指定就报错。

解决:连接 URL 里同时加上 allowPublicKeyRetrieval=true 和 serverTimezone=Asia/Shanghai。如果用的是 5.7 或更早版本,驱动选 com.mysql.jdbc.Driver;8.0 用 com.mysql.cj.jdbc.Driver,两版驱动类名不同,写错就报 ClassNotFoundException。这条在本地 MySQL 安装配置完成后第一次跑项目时几乎是必踩的。

5.2 中文乱码:URL 编码、表字符集、客户端编码三处对齐

现象:往 MySQL 里插入中文姓名后,查询出来变成问号,或者插入时直接报 Incorrect string value。

原因:三层里任意一层没对齐都会乱码。第一层是 JDBC 连接串没指定 characterEncoding=utf8;第二层是表或库的字符集不是 utf8mb4;第三层是 Java 源码文件本身的编码和编译器读取时不匹配。

解决:连接串加 useUnicode=true&characterEncoding=utf8;建库语句里显式指定 DEFAULT CHARACTER SET utf8mb4;IDEA 里把 File Encoding 改成 UTF-8。遇到已经建好的表,用 ALTER TABLE student CONVERT TO CHARACTER SET utf8mb4 补救。这条血泪经验是每个做课程设计的人都躲不掉的坑。

5.3 Swing 界面假死:耗时查询别放在事件线程里

现象:点「统计」按钮之后整个窗口卡住,拖动窗口都没反应,数据库查询执行几秒,界面就白屏几秒,像死机一样。

原因:Swing 是单线程模型,所有事件回调都跑在 Event Dispatch Thread 上。查询数据库是阻塞操作,放在按钮监听器里直接把 EDT 堵住,界面自然无法重绘。

解决:把耗时操作放到 SwingWorker 里。

new SwingWorker<Void, Void>() { @Override protected Void doInBackground() { List<StatItem> items = statService.loadStat(); return null; } @Override protected void done() { barPanel.removeAll(); barPanel.add(createBarChart(items)); barPanel.revalidate(); barPanel.repaint(); } }.execute();

doInBackground 在后台线程执行数据库查询,done 在主线程里更新界面。这是 Swing 编程里最核心的线程约定,答辩时能主动说出来,老师会认为你是真的理解了 Swing 机制。

5.4 驱动找不到与 No suitable driver:jar 包导入的两种正确姿势

现象:代码里明明写了 Class.forName("com.mysql.cj.jdbc.Driver"),运行时还是报 ClassNotFoundException,或者报 No suitable driver found for jdbc:mysql://...

原因:mysql-connector 的 jar 没有进入运行时 classpath。课程设计一般用 IDEA,常见错误是把 jar 下载到桌面就用,没有点右键选择 Add as Library,或者通过 Project Structure 添加了却没选对模块。

解决:lib 目录下的 jar 在 IDEA 里右键选择 Add as Library,并确认 Artifacts 的 Output Layout 里包含该 jar。如果最终要打包成可执行 jar,最好用 IDEA 的 Artifacts 把所有依赖打成 fat jar,否则运行 java -jar 时同样会找不到驱动。

5.5 外键约束导致删除失败:先删关联表再删主表

现象:删除一条宿舍记录时抛出 Cannot delete or update a parent row: a foreign key constraint fails。

原因:student 表有学生还关联在这个宿舍上,checkin 表也有对应记录,外键约束不允许直接删主表数据。

解决:按依赖顺序清理,先删 checkin、再清 student 里的引用,最后删 dormitory。也可以在业务层做逻辑删除,给 dormitory 加 status 字段,不真正物理删除。课程设计的演示场景里,让学生先「退宿」再删宿舍是符合管理直觉的流程,比直接弹数据库错误框体验好得多。

6. 交付前的最后一道工序:打包可执行 jar 与答辩演示准备

6.1 把依赖打进一个 fat jar:IDEA Artifacts 配置与外部化 db.properties

确认功能全部跑通后,要把项目打成可执行 jar。IDEA 的 Project Structure -> Artifacts 里添加一个 JAR From modules with dependencies,主类选到 com.dorm.Main,Output Layout 会把引入的 mysql-connector、jfreechart 全部打进这个 fat jar。打出来后,在命令行 java -jar dorm-manage.jar 能直接拉起登录窗口,才算真正交付。数据库账号密码此时需要从代码里抽出来放到 db.properties,文件放在 jar 同目录,程序启动时用 Properties 加载,这样现场答辩如果换了机器,改一个配置文件就能连库,不需要重新编译。

6.2 答辩演示前自检清单与 15 分钟演示动线

答辩演示通常只有十几分钟,不要指望评委自己点。建议按这条动线走:启动程序进入登录页,输入 admin 账号,进入主界面展示功能菜单;先查宿舍列表,说明宿舍楼、房间、床位的层级关系;然后登记一名学生入住,现场执行一次插入操作,让学生表数据涨一条;接着按楼统计入住人数,切换图表面板,展示柱状图和饼图;最后点导出按钮,确认桌面生成了一张 PNG 截图。这条动线覆盖了一层增删改查、一层统计聚合、一层图表展示和一层文件导出,基本把课程设计评分点全部踩到。文档里也建议放一张 E-R 图、每张表的字段说明和一个测试用例表。

这个项目做完后印象最深的不是界面代码,而是数据模型一旦定错,后面所有 SQL 都要跟着返工。第一次做的时候我在 student 表里直接塞了多个宿舍字段,后来统计入住率时发现左连接写不出来,被迫重建立表。如果你时间紧,优先保证登录、登记、统计、导出四条链路完整,再去补花哨样式。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询