简介一套基于Java与SQL Server的GUI学籍管理系统面向高校数据库或Java课程设计场景帮助学习者掌握桌面端管理系统开发与数据库权限控制的完整流程。压缩包共52个文件主要包含24个Java源码、5个SQL脚本以及txt数据导入文件、docx使用说明书、png/jpg操作截图和演示PPT整体大小2.55MB。系统功能覆盖学生信息批量导入与手动维护、班级增删改查、按学号或课程号修改成绩、按多种条件查询学生及任课教师、教学计划管理、自定义开除预警条件并通过数据库权限控制实现登录后的功能差异化。附带的SQL脚本涵盖建库建表、视图、存储过程、函数与用户授权配置说明和截图辅助理解运行过程。目前已有233人学习适合需要完整参考课程设计项目或学习Java与SQL Server集成开发的读者。1. 一个能跑的 Java Sql Server 学籍管理系统课程设计拿高分的前置认知看到“基于 Java Sql Server 实现的 GUI 学籍管理系统”这个资源时我的第一反应是看它到底能不能直接跑起来。拆完之后可以负责任地说这不是一个只有脚手架的半成品而是数据库脚本、界面程序、需求分析文档都齐的完整课程设计。它用 Java Swing 搭 GUI用 Sql Server 存数据核心功能包括 txt 批量导入学生/成绩/课程、班级增删改查、按学号或课程号改成绩以及一个靠“选修未完成学分限制 必修未完成学分限制 学期必修未完成学分限制”组合判断的开除名单查询。适合正在做数据库课程设计、想从别人完整项目里学 JDBC 与存储过程配合的人。这个资源最值钱的地方不在那个 jar 包而在它把数据库侧的建表、视图、函数、存储过程、用户授权全部单独拆成了 sql 文件还把需求分析和使用说明书放在一起。这意味着你可以从数据层一路看到界面层而不是对着一个黑匣子瞎猜。接下来我从数据库脚本开始拆再到 GUI 功能和答辩准备最后把最容易翻车的几个点单独拎出来说。2. 先把数据库立起来建库、建表、视图、存储过程与授权脚本怎么执行2.1 从文件名识破脚本执行顺序别上来就运行 2建表语句.sql打开压缩包后第一眼看到的是“2建表语句.sql”“3视图语句.sql”“5用户授权语句.sql”“1函数语句.sql”“4存储过程语句.sql”。数字编号给你了执行顺序的提示但真实项目中数字不代表完整顺序。因为 SQL Server 里视图和存储过程会依赖表结构函数也可能被视图调用所以必须先建库再建表然后创建函数、视图、存储过程最后做用户授权。我一般这么处理先用 SQL Server Management Studio 新建一个数据库名字可以叫 StudentDB然后把“2建表语句.sql”放进去执行。如果表之间是外键关系建议先执行父表学生表、课程表再执行子表成绩表。别指望用 SSMS 的“执行全部脚本”一次通过——很多课程设计里的脚本顺序是乱的报错信息会告诉你依赖哪个对象不存在。实际执行顺序可以这样安排# 在 SSMS 中按以下顺序逐个打开脚本文件执行 1. 数据库建库语句如果有单独 sql 就先跑 2. 2建表语句.sql 3. 1函数语句.sql 4. 3视图语句.sql 5. 4存储过程语句.sql 6. 5用户授权语句.sql这段逻辑要注意项目文件名里数字是“3视图、5授权、1函数、4存储过程、2建表”我把 1 放前面是因为函数必须先于视图。如果压缩包里没有单独的建库语句也可以在 SSMS 里手动右键新建数据库。这不是玄学是 SQL Server 对象依赖关系决定的。2.2 建表语句里的功课学号、课程号、成绩表外键怎么设计学籍管理系统最少需要三张核心表学生表、课程表、成绩表。学生表的主键一般是学号课程表主键是课程号成绩表用“学号 课程号”做联合主键同时这两列都是外键。这种设计才能保证一条成绩记录对应一个真实存在的学生和一门真实存在的课程。-- 典型的学生表结构课程设计常见做法 CREATE TABLE T_Student ( 学号 VARCHAR(20) PRIMARY KEY, 姓名 NVARCHAR(50) NOT NULL, 性别 NVARCHAR(10) CHECK (性别 IN (男,女)), 班号 VARCHAR(20), 入学日期 DATE ); CREATE TABLE T_Course ( 课程号 VARCHAR(20) PRIMARY KEY, 课程名 NVARCHAR(50) NOT NULL, 学分 NUMERIC(4,1) NOT NULL ); CREATE TABLE T_Score ( 学号 VARCHAR(20) NOT NULL REFERENCES T_Student(学号), 课程号 VARCHAR(20) NOT NULL REFERENCES T_Course(课程号), 成绩 NUMERIC(5,2) CHECK (成绩 BETWEEN 0 AND 100), 学期 VARCHAR(20), 是否必修 BIT, PRIMARY KEY (学号, 课程号) );这里把学号和课程号都定成 VARCHAR因为很多高校的学号带字母用 int 会在导入时翻车。性别加 CHECK 约束能挡住脏数据。是否必修用 BIT 而不是字符串‘是/否’是为了后面计算“必修未完成学分”时可以直接 SUM。学分用 NUMERIC(4,1)允许 0.5 这种值。如果你在原项目的建表脚本里看到类似的写法说明作者考虑过数据完整性。2.3 函数与视图把“未完成学分”判断下沉到 SQL 层这个项目里有一个很有价值的做法把“什么算未达标”的判断放在数据库函数和视图里而不是 Java 代码里。这样 GUI 端每次点查询只是调用一个视图规则改了也只改 SQL。拆项目时我特别留意了“1函数语句.sql”和“3视图语句.sql”的边界函数负责按学号统计已获得学分视图负责把不达标的学生和缺失项拼成一张明细表。-- 函数统计某学生某类课程已获得学分示例 CREATE FUNCTION dbo.GetPassedCredit( studentId VARCHAR(20), requiredType BIT ) RETURNS NUMERIC(6,1) AS BEGIN DECLARE credit NUMERIC(6,1); SELECT credit ISNULL(SUM(c.学分), 0) FROM T_Score s JOIN T_Course c ON s.课程号 c.课程号 WHERE s.学号 studentId AND s.成绩 60 AND s.是否必修 requiredType; RETURN credit; END;函数接受两个参数学号和课程类型。这里把是否必修当成 BIT 传入1 表示必修0 表示选修。成绩大于等于 60 才算通过否则不累加学分。ISNULL 包裹 SUM 是为了防止没有成绩时返回 NULL导致后续判断出错。视图层面再把这个函数和总学分要求做对比就能得到“未完成学分”清单。使用函数和视图的好处是GUI 端的查询代码可以变得非常薄。比如自定义开除判定界面只需要接收三个限制值选修未完成学分限制、必修未完成学分限制、学期必修未完成学分限制然后传给一个视图或存储过程不必在 Java 里写一堆循环。2.4 存储过程加用户授权GUI 登录背后的权限模型项目的“4存储过程语句.sql”和“5用户授权语句.sql”是配套的。存储过程封装业务查询比如“按学号查询所有教过该学生的任课老师姓名”用户授权脚本则把特定数据库账号的权限限定到这几条存储过程上。这比直接在 GUI 里用 sa 连数据库要安全得多也能解释为什么需求里写了“登陆登出功能利用数据库权限控制指定用户所可拥有的功能”。-- 创建按学号查任课老师的存储过程 CREATE PROCEDURE usp_GetTeachersByStudent studentId VARCHAR(20) AS BEGIN SELECT DISTINCT t.教师姓名 FROM T_Teacher t JOIN T_TeachingPlan tp ON t.教师编号 tp.教师编号 JOIN T_Score s ON tp.课程号 s.课程号 AND tp.学期 s.学期 WHERE s.学号 studentId; END; GO -- 授权示例 CREATE LOGIN app_user WITH PASSWORD StrongPss123; CREATE USER app_user FOR LOGIN app_user; GRANT EXECUTE ON usp_GetTeachersByStudent TO app_user;存储过程用 DISTINCT 是因为同一门课可能由同一个老师在一个学期教多次但最终要返回的是“教过哪些老师”重复的要去掉。授权脚本里 CREATE LOGIN 是登录级CREATE USER 是数据库级GRANT EXECUTE 只允许执行存储过程不给直接 SELECT 表的权限。这样 GUI 登录时用的就是 app_user而不是数据库管理员账号。课程设计里能做到这层的已经比多数同学高出不少。3. GUI 功能拆解txt导入、手动录入、按学号改成绩与自定义开除判定3.1 txt 导入前先看表头学生、成绩、课程三种文件的格式约定项目支持用 txt 导入学生信息、成绩、课程信息。这类功能最常见的坑是格式约定和编码。拿到代码后先打开一个示例 txt 看第一行是列名还是直接从数据开始。课程设计里常见格式是第一行是列名第二行开始是数据字段之间用 Tab 或逗号分隔。下面的代码演示了读取 txt 并批量导入学生表的过程// 导入学生信息 txt 的简化逻辑 try (BufferedReader reader Files.newBufferedReader( Paths.get(students.txt), StandardCharsets.UTF_8)) { String line; boolean firstLine true; ListStudent students new ArrayList(); while ((line reader.readLine()) ! null) { if (firstLine) { firstLine false; continue; } // 跳过表头 String[] cols line.split(\t); // 以 Tab 分隔 if (cols.length 4) continue; // 防坏行 Student s new Student(cols[0], cols[1], cols[2], cols[3]); students.add(s); } // 批量插入 String sql INSERT INTO T_Student (学号,姓名,性别,班号) VALUES (?,?,?,?); // 用 PreparedStatement addBatch 实现批量 }这里读取时指定 StandardCharsets.UTF_8如果原文件是 GBK 就会乱码后面避坑章会细说。跳过第一行是因为表头不是数据。split(\t) 是按 Tab 分隔如果原文件是逗号就要改成 split(,)并小心数据里有没有逗号。批量插入用 addBatch 可以显著提升速度但要注意批处理中某一行出错时先捕获异常定位行号而不是直接抛给用户看“导入失败”。3.2 手动录入与批量修改主键冲突、空值和事务控制手动录入学生信息时最容易被忽视的是主键冲突。学号重复时SQL Server 会报“违反主键约束”程序层面要提前查一次或者捕获 SQLIntegrityConstraintViolationException。批量修改班级则相对简单本质是一条 UPDATE 语句把某个班的学生的班号统一改成新班号。删除学生时要考虑成绩表的外键否则会报外键冲突。// 批量改班级的核心 SQL String updateSql UPDATE T_Student SET 班号 ? WHERE 班号 ?; try (PreparedStatement ps conn.prepareStatement(updateSql)) { ps.setString(1, newClassId); ps.setString(2, oldClassId); int rows ps.executeUpdate(); System.out.println(影响行数 rows); }执行顺序是先改学生表再处理成绩表。如果 GUI 里只是修改班级不需要动成绩表因为成绩表通过学号关联学生不依赖班号。影响行数可以用来做操作反馈。删除学生时程序最好先检查成绩表有没有记录或者用级联删除。课程设计里最简单的方式是在成绩表外键上设置 ON DELETE CASCADE但这样做有风险可能把不该删的连带删掉。更稳妥的是在 Java 里先弹确认框再执行删除。3.3 按学号改成绩和按课程号改成绩两条路线哪个更合理项目的“提供按学号修改成绩及按课程号修改成绩功能”意味着 GUI 有两条更新路径。按学号改成绩通常出现在“单个学生成绩纠错”场景界面输入学号后拉出该生所有成绩选择课程后修改分数按课程号改成绩则是“这门课全班统一加分”的场景根据课程号列出所有选了这门课的学生直接改某一个或全部。-- 按学号修改某课程成绩 UPDATE T_Score SET 成绩 ? WHERE 学号 ? AND 课程号 ?; -- 按课程号批量修改成绩例如统一加 5 分控制在 100 分内 UPDATE T_Score SET 成绩 CASE WHEN 成绩 5 100 THEN 100 ELSE 成绩 5 END WHERE 课程号 ?;第一条语句用三个条件定位唯一一条成绩记录前提是成绩表主键是“学号 课程号”。第二条用 CASE 防止加分后超过 100 分这是我在实际使用中吃过亏的地方——原来的课程设计直接写“成绩 成绩 5”结果有学生成绩变成了 103后面做统计时全乱了。按课程号批量改成绩最好加一个是否“只修改不及格”的勾选框需求里没提但答辩时老师很爱问这类边界条件。3.4 自定义开除判定把三个学分限制组合成查询条件这个项目最亮眼的是自定义查询将被开除学生功能。它允许同时设定三个限制选修未完成学分、必修未完成学分、学期必修未完成学分。这三个条件不是固定死的而是用户输入的数值。实现上最好用动态 SQL 拼接把用户输入为空的条件过滤掉。// 动态拼接开除判定查询的伪代码 ListString whereList new ArrayList(); if (electiveLimit ! null) { whereList.add(dbo.GetPassedCredit(s.学号, 0) electiveLimit); } if (requiredLimit ! null) { whereList.add(dbo.GetPassedCredit(s.学号, 1) requiredLimit); } // 学期必修未完成限制需要额外函数/视图这里略 String sql SELECT 学号, 姓名, 班号 FROM T_Student s WHERE String.join( OR , whereList);这里处理的关键是三个限制之间应该是“OR”还是“AND”按业务语义只要有一个限制不满足就属于未达标所以用 OR。但有些同学会把它们拼成 AND导致查出来的学生越来越少。另一个关键点是参数类型用户可能输入“选修 10、必修 20、学期必修 5”如果选修文本框中留空就不要加入条件。动态 SQL 要注意防注入课程设计里可以用 PreparedStatement 的占位符拼 SQL不要直接把用户输入拼进字符串。安全习惯要从课程设计开始养成。4. 从说明书到答辩需求分析文档怎么读、演示路径怎么设计4.1 需求分析文档怎么读先画功能树压缩包里有“需求分析等”文件夹还有“学籍管理系统使用说明书.docx”很多人下载后只盯 jar 包忽略文档。但课程设计答辩时老师不会只看运行效果更会问“你的数据库为什么这样设计”“这个功能满足什么需求”。项目里那份需求分析文档如果包含用例、功能模块划分那它就是答辩的底稿。我会先把使用说明书读一遍尤其是功能列表和操作流程它能帮你快速知道 GUI 上每个按钮对应什么动作。读文档时不要从头到尾通读先画功能树学生信息管理、成绩管理、班级管理、教学计划管理、开除判定、用户权限。每看到一个功能就回到代码里找到对应的类和方法。比如“批量修改班级”在 GUI 上是一个按钮在数据库侧就是一条 UPDATE 语句在 Java 侧是一个 PreparedStatement。这样把文档、代码、数据库三者连起来答辩时就敢说“这个功能是我实现的”而不是“这个项目是我下载的”。4.2 把 GUI 功能映射到数据库对象一张表看懂架构我习惯把功能点和数据库对象做一张映射表这对快速定位问题和答辩都很有用。下面的表是通用的对应关系你可以按项目实际脚本调整GUI 功能数据库对象关键点学生列表/查询T_Student 表学号主键、班号索引成绩录入/修改T_Score 表联合主键、外键约束按学号查任课老师usp_GetTeachersByStudent 存储过程多表 JOIN DISTINCT开除判定GetPassedCredit 函数 视图学分阈值比较登录/登出数据库登录名/用户GRANT EXECUTE 权限有了这张表哪怕原项目代码风格比较乱你也能在半小时内理清核心路径。答辨时如果老师问“开除判定怎么实现的”你可以直接说“我写了一个函数统计学分再在视图里过滤未达标学生GUI 只负责传三个限制值”比支支吾吾翻代码强得多。4.3 演示路径设计从登录到导入再到开除判定拿到一个完整项目不要从头到尾乱点。我建议按“登录 → 导入 → 查询 → 修改 → 自定义开除判定”的顺序演示时间控制在五分钟。登录时刻意用权限低的账号演示一次受限功能说明你理解用户授权导入 txt 时提前准备好一个 UTF-8 编码的文件不要现场从记事本编数据容易翻车自定义开除判定是亮点要把三个学分限制的输入过程展示出来并解释为什么用 OR。# 快速启动 jar 包的推荐命令 java -jar 学籍管理系统-03111002.jar这里的 jar 包是项目编译好的程序运行前提是本机已经配置好 JAVA_HOME并且 Sql Server 的端口、数据库名、账号密码与代码中的配置文件一致。如果启动就报数据库连接错误优先检查 Sql Server 服务有没有开启而不是怀疑 jar 包坏了。演示前最好先登录一次把常用数据查出来避免连数据库的等待时间冷场。4.4 答辩前的自问自答老师最常问的五个问题课程设计答辩不是代码 review老师更关注你能不能讲清楚设计决策。我总结过五个高频问题这套资源的需求分析文档基本都能覆盖第一个问题为什么用存储过程而不是直接在 Java 里写 SQL回答存储过程可以封装复杂业务规则还能通过 GRANT EXECUTE 做细粒度权限控制避免给普通用户直接查表的权限。第二个问题开除判定的三个限制条件之间是什么关系回答是“或”的关系任一未达成即进入待开除名单符合学校学籍预警的实际情况。第三个问题txt 导入时怎么处理重复学号回答可以先查一次判断或者批量插入时捕获主键冲突把失败行写到日志里。第四个问题如果成绩表中某学生没有选课记录开除判定会怎么显示回答函数里用 ISNULL 把 NULL 转成 0所以该生会被判为学分未完成这正是学校盯紧的对象。第五个问题你的系统能防 SQL 注入吗回答所有用户输入都走 PreparedStatement 参数绑定动态条件拼接的值也被当作参数而不是直接拼到 SQL 字符串里。多花一小时准备这四个问题比多写一百行代码更有答辩价值。5. 避坑与排查Sql Server 连接、jar 运行和权限控制的五个典型问题5.1 连接不上数据库Tcp 协议未启用或端口不对现象jar 包启动后提示类似“The TCP/IP connection to the host ... failed”的错误GUI 一直卡在登录界面。原因Sql Server 安装后默认可能没有启用 TCP/IP 协议或者端口不是 1433而 Java 程序用 localhost:1433 连接。还有可能是 Sql Server 服务本身没启动尤其在 Windows 上装了多个实例的时候默认实例和服务名对不上。解决打开 Sql Server Configuration Manager找到“SQL Server 网络配置”启用 TCP/IP确认端口为 1433然后重启 Sql Server 服务。如果改了端口要同步改 Java 代码里的连接串。排查时先用 SSMS 本地连一次数据库确认服务是活的再看配置管理器。5.2 驱动类找不到ClassNotFoundException现象运行 jar 或源码时抛出 java.lang.ClassNotFoundException: com.microsoft.sqlserver.jdbc.SQLServerDriver。原因缺少 Sql Server 的 JDBC 驱动 jar或者驱动没有放进 lib 目录。很多课程设计压缩包里只有源码和 jar不附带 mssql-jdbc 驱动运行时就会踩这个坑。解决到 maven 仓库或 Sql Server 安装目录下载对应版本的 mssql-jdbc-*.jar放入项目 lib 文件夹。在 IDE 里要右键 Build Path 添加直接用 java -jar 时通常要把驱动 jar 和项目 jar 放在一起或者用 -cp 参数指定。注意驱动版本要和 Sql Server 版本匹配2008 用旧版驱动2019 可能要用新版否则连接时会报协议错误。5.3 txt 导入后中文乱码现象GUI 里显示的学生姓名全是“锟斤拷”之类的乱码但 SSMS 里直接插入中文正常。原因txt 文件是 GBK 编码而 Java 读取时用了 UTF-8或者反过来。Windows 记事本默认保存的是 ANSIGBK而代码里强制指定 UTF-8就会把字节流按错误的字符集解码。解决统一把所有 txt 文件以 UTF-8 保存。如果文本里已经乱码建议用 Notepad 或 VS Code 重新转换编码再导入。在 Java 代码里读取时显式指定 StandardCharsets.UTF_8。另外要注意SQL Server 里的字符类型如果是 VARCHAR中文可能存不进去最好用 NVARCHAR。检查一下建表语句里姓名、课程名是否是 NVARCHAR是的话就不会因为排序规则导致乱码。5.4 存储过程执行权限被拒绝现象用普通账号登录 GUI 后点“查询任课老师”提示“The EXECUTE permission was denied”。原因用户授权语句只给账号创建了登录名但没有对存储过程授予 EXECUTE 权限或者授权顺序在存储过程创建之前执行导致权限没有生效。还有一种情况是 GUI 连接串用的不是授权账号而是 sasa 当然有权限但这样就没法演示权限控制了。解决重新执行“5用户授权语句.sql”确认包含 GRANT EXECUTE ON 具体存储过程名 TO 用户名。如果是在授权之后新建的存储过程需要再补一次授权。检查时用 SSMS 登录该账号执行“SELECT * FROM fn_my_permissions(NULL, DATABASE)”看权限列表能看到 EXECUTE 才算真正生效。5.5 GUI 查不到刚改的数据现象在界面里修改成绩后再点查询结果还是旧分数但用 SSMS 查数据库已经是新值。原因最常见的是程序里没有提交事务或者查询用的连接和修改用的连接不是同一个又或者是修改操作把异常吞掉了。有些课程设计为了图简单每次操作都 new 一个 Connection但忘记 commit连接关闭时事务回滚界面上看着像成功实际没写进去。解决在 JDBC 里开启事务后要记得 commit如果使用多条连接查询前要重新打开连接而不是复用已经关闭的。最简单的验证方式是在 GUI 改完后立即用 SSMS 查询如果数据库有变化但 GUI 没变化那就是查询逻辑问题去看看查询按钮的事件里是不是用的旧数据源。还可以在 Java 代码里加一行 System.out.println(conn.getAutoCommit())确认自动提交是不是被意外关掉了。6. 收尾从“跑通”到“讲得清”的验证清单最后这一部分我想分享一个验证习惯。拿到这类课程设计资源不要急着交作业先用下面这个清单过一遍。第一数据库层按顺序执行完所有脚本后用 SSMS 查询学生表、课程表、成绩表的行数再分别测试“函数算学分”和“视图查未达标明细”是否返回预期结果。第二GUI 层用不同权限账号登录记录各自能看到的菜单和功能确认用户授权不是摆设。第三数据流从 txt 导入一条新学生再到界面查询这条学生最后修改他的成绩确认三步都走通。第四逻辑边界把自定义开除判定里三个限制分别设为 0 和极大值看查询结果是否合理。验证时可以把这个表打印出来验证点操作预期结果建表执行 2建表语句.sql三张核心表存在且主外键正确视图执行 3视图语句.sql未达标明细视图能返回数据开除判定设定三限制满足任一未达标即出现在列表权限低权限账号登录受限功能按钮不可用或报权限错误这套清单我陪好几个学弟调过几乎每次都能在答辩前把隐藏问题揪出来。有一次因为视图里用了 LEFT JOIN被开除的学生在成绩表没有记录时学分显示 0判定逻辑看起来不成立后来在函数里加 ISNULL 才解决。从那以后我每次跑别人的课程设计都会强制先把数据库脚本按依赖顺序重跑一遍再打开 GUI而不是直接双击 jar 包碰运气。希望这套流程能帮你在答辩前少踩几个坑让这份 Java Sql Server 的 GUI 学籍管理系统真正变成你能讲清楚、用顺手的东西。本文还有配套的精品资源点击获取