news 2026/9/28 8:25:01

Java Swing+MySQL学生选课及成绩管理系统:完整CRUD项目详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java Swing+MySQL学生选课及成绩管理系统:完整CRUD项目详解

简介:这是一套基于Java + Swing + MySQL的学生选课及成绩管理系统课程设计,适合Java初学者或希望掌握桌面应用开发的学习者,可作为毕业设计、课程设计、大作业或工程实训的完整参考。项目覆盖登录、学生信息管理、课程管理、选课及成绩管理等核心功能,内置管理员、教师、学生三类测试账号,数据库配置和SQL脚本均随包提供,便于快速运行与二次开发。资源共53个文件,以Java源码、JPG界面截图、XML配置和SQL脚本为主,另含PNG数据库E-R图与README说明,整体压缩包仅8.63MB。截图覆盖登录、选课、成绩管理等主要界面,可直观展示系统功能与交互流程。目前已有219人学习使用,适合用来理解Swing界面编程、JDBC数据库操作以及分层项目组织方式,也可作为课程答辩或项目文档的实用素材。

1. 基于 Java + Swing + MySQL 的学生选课及成绩管理系统:课设表象下的完整 CRUD 样本

这套系统的压缩包解压后,第一眼看上去就是标准的课设模板:src 目录、lib 下躺着 mysql-connector-j-8.3.0.jar、document 里塞满了界面截图和 E-R 图。但等我把 SQL 脚本导入 MySQL 8、在 IDEA 里跑通登录后,发现它比很多挂着“系统”名头的付费项目扎实得多——管理员、教师、学生三种角色权限分离,选课和成绩录入用的是同一套 JDBC 逻辑,甚至数据库配置类都单独抽了出来。对正在找 Java 课程设计案例源码的人来说,这套项目最值钱的地方不是功能多炫,而是能让你完整看到 Swing 表单和 MySQL 表之间是怎么通过 JDBC 串起来的。想啃下 Java 基础、需要交数据库课设、或者想快速搭一个桌面端 CRUD 原型做毕设起点的人,都值得在电脑里留一份。

2. 从源码到跑通:环境准备、项目导入与数据库初始化

2.1 先把 JDK、IDEA、MySQL 对齐,别让版本拖后腿

课程设计最常见的问题不是代码写错,而是环境不对。这套系统的 README 里明确写了开发工具组合:JDK 1.8、IDEA、MySQL 8.0.36、Navicat 16。从工具版本能看出,项目作者是在一个非常典型的 Windows 课设环境下完成调试的,这也意味着你用同样的组合去跑,踩坑概率最低。JDK 1.8 对 Swing 支持最稳定,不需要额外引入 JavaFX;MySQL 8.0.36 对应 mysql-connector-j-8.3.0 驱动,两者兼容性没问题。如果你电脑里装的是 MySQL 5.7,驱动也能用,但部分 SQL 语法和字符集默认值会有细微差别,后面我会在避坑章节细说。

建议先自查三个工具的版本,再继续往下走。打开命令行:

java -version mysql --version
# 如果提示 mysql 不是内部或外部命令,说明 MySQL 没装进 PATH # 要么重新安装并勾选 Add to PATH,要么用安装目录下的 bin/mysql.exe 代替

JDK 输出到 1.8.0_xx 就没问题。MySQL 输出 8.0.xx 最好。如果没装 MySQL,不要凭感觉从网上下最新版,按 mysql 安装教程走,安装时记住 root 密码。Navicat 16 不是必需的,但用它执行 SQL 脚本和看表结构最直观,我用的是这个工具,后面导入 SQL 脚本的步骤也以它为例。至于 IDEA,社区版就够,课程设计不需要付费版特性。

确认完环境后,打开 IDEA,选择“File > New > Project from Existing Sources”,然后定位到解压后的 StuSystem 文件夹,选择 Maven 或普通项目都可以——不过这套源码大概率不是 Maven 结构,所以选“Import project from external model”时,如果它提示找不到 pom.xml,就直接选“Next”按普通 Java 项目导入。导入后 IDEA 会自动识别 src 目录,但 lib 下的 mysql-connector-j-8.3.0.jar 需要你手动添加依赖:右键 lib 目录,选择“Add as Library”,确认把 jar 包挂到项目模块上。这一步漏了的话,编译期不会报错,运行一调用 Class.forName 就抛 ClassNotFoundException。

2.2 解压 StuSystem.zip,看清目录再动手

项目压缩包内部目录结构非常规整,即使没有 README,光看文件夹名也能猜到一半功能。下面是解压后主要内容的说明:

文件或目录用途
src/comJava 源码包,包含界面类、业务逻辑类、数据库配置类
lib/mysql-connector-j-8.3.0.jarMySQL JDBC 驱动,8.3.0 版本
src/resources/sql数据库初始化脚本,导入 MySQL 后得到所有表结构和初始数据
document系统结构图、E-R 图、各界面截图,写课设报告时直接能用
README.md项目说明和默认账号密码

src 目录下还有 .idea 文件夹,说明作者用的是 IDEA 保存的工程配置,这也可以作为该资源是“IDEA 原生开发”的佐证。但我不建议直接用他的 .idea,因为每个人的本地 JDK 路径和配置不同,容易把模块加载错误带过来。我一般会手动新建一个普通 Java 项目,再把 src 复制进去,然后手动导入 lib。

这里有一个值得留意的点:源码在 src/com 下分层,常见包名是 com.ui(登录页面和主窗体)、com.service(业务逻辑)、com.dao(数据访问)、com.model(实体类)。从项目正文提到的 JdbcConfig 来看,数据库连接配置被放在了 com.service 包下,说明作者把“获取数据库连接”当作服务来处理,这比把连接 URL 散落在每个 DAO 类里要好。你可以打开 src/com/service/JdbcConfig 看一下,代码里大概率写死了一组常量:

package com.service; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class JdbcConfig { // 本地数据库地址,3306 是 MySQL 默认端口 private static final String URL = "jdbc:mysql://localhost:3306/stusystem?useSSL=false&serverTimezone=Asia/Shanghai"; private static final String USER = "root"; private static final String PASSWORD = "123456"; static { try { // 注册驱动,8.x 使用 com.mysql.cj.jdbc.Driver Class.forName("com.mysql.cj.jdbc.Driver"); } catch (ClassNotFoundException e) { e.printStackTrace(); } } public static Connection getConnection() throws SQLException { return DriverManager.getConnection(URL, USER, PASSWORD); } }

这段代码的逻辑很直白:先加载驱动类,再通过 DriverManager 拿连接。URL 里的 useSSL=false 是 MySQL 8 驱动连接本地库时的常用配置,如果你看到项目里没有加这个参数,后面排查 SSL 错误时可以补上。USER 默认 root,PASSWORD 默认 123456,和 README 里说的一致。如果你本地 MySQL 密码不是 123456,改这一处就够了,但前提是你要先完成下一步的数据库初始化,不然改了密码也连不上空库。

2.3 初始化数据库:执行 SQL 脚本,改对连接参数

数据库脚本放在 src/resources/sql 下,文件名以解压后的实际 .sql 文件为准,常见的是 init.sql 或 stusystem.sql。拿到脚本后不要急着双击运行,先确认你要创建的库名和连接 URL 保持一致。以 JdbcConfig 里 URL 为 stusystem 为例,你可以用 Navicat 执行,也可以直接用命令行:

mysql -u root -p < src/resources/sql/stusystem.sql
# 如果提示 mysql 命令不存在,cd 到 MySQL 安装目录的 bin 下再执行 # 比如:cd "C:\Program Files\MySQL\MySQL Server 8.0\bin" # mysql -u root -p < D:\StuSystem\src\resources\sql\stusystem.sql

执行过程中会输入 root 密码。脚本里应该包含 CREATE DATABASE、CREATE TABLE 和 INSERT 初始数据的语句。如果脚本本身没有 CREATE DATABASE,你需要先在 Navicat 里手动创建一个名为 stusystem 的数据库,字符集选 utf8mb4,再运行脚本。否则后面 JdbcConfig 连接时会报“Unknown database”。

脚本导入成功后,在 Navicat 里刷新,应该能看到 student、teacher、course、sc(选课表)等表。注意初始数据的登录账号是硬编码在脚本里的:管理员 admin/123,教师 tch/123,学生 stu/123。你可以打开对应的表确认密码字段是否是明文,是明文的话,说明这属于教学项目惯例,方便演示,同时也意味着如果要投产用,密码加密是必改项。

接下来启动系统。在 IDEA 里找包含 main 方法的入口类,通常是 com.ui.LoginFrame 或 MainFrame,右键运行。如果弹出一个 Swing 登录窗口,说明项目已经跑通。如果报数据库连接失败,优先回头看 JdbcConfig 里的密码是否改到位,以及脚本是否成功创建了库。这两个地方是新手最容易卡住的点。

3. 数据库表设计和权限模型:三类角色是怎么串起来的

3.1 从 E-R 图反推表结构:学生、教师、课程、选课、成绩的关系

document 目录下的“数据库E-R图.png”给出了整个系统的核心关系。从命名上看,表设计遵循经典的教务管理模型:学生和课程之间是多对多关系,通过选课表(sc)作为中间表,而成绩就是选课表上的一个附加属性。教师和课程之间则是一对多关系,一个教师可以教多门课。这个模型在数据库课程设计中属于标准答案,没有花哨设计,但足够支撑选课和成绩管理的全部业务。

常见的表结构是这样的:

表名作用关键字段建议
student学生信息sno(学号)、sname、ssex、sdept、password
teacher教师信息tno(工号)、tname、tdept、password
course课程信息cno(课程号)、cname、credit、tno(授课教师)
sc选课表sno、cno、score(成绩)
admin管理员信息账号、密码

从界面截图也能印证这个设计:学生信息管理界面里必然有学号和姓名列,学生选课界面里有课程列表和选课按钮,学生课程成绩管理界面里有成绩列。E-R 图里这三张核心表的关系可以转化为一条联合查询 SQL,这也是成绩查询界面的底层逻辑:

SELECT s.sname AS 学生姓名, c.cname AS 课程名称, sc.score AS 成绩 FROM student s JOIN sc ON s.sno = sc.sno JOIN course c ON sc.cno = c.cno WHERE s.sno = 'stu';
-- 上面的 WHERE 条件在真实代码里会用 PreparedStatement 的 ? 占位符替换 -- 查询效果:把学生选的所有课和对应成绩一次性查出来

这条 SQL 是理解整个系统业务的关键,也是你在答辩时最容易被追问的语句。值得注意的是 sc 表中的 score 字段可空——学生刚选课还没考试时,这条选课记录存在,但成绩是 NULL。成绩录入功能本质上就是对 NULL 值做 UPDATE,而不是 INSERT。

3.2 三类角色的权限边界:管理员管人、教师管课、学生选课

如果把系统看成一个黑匣子,登录框的下拉选角色就是黑匣子的第一道开关。项目里有三种角色,它们的数据操作边界完全不同:

角色能操作的功能数据影响范围
管理员学生信息管理、教师信息管理、课程管理、系统报表可以增删改所有用户和课程
教师成绩录入、成绩修改、查看所授课程名单只能操作自己负责的课程和学生成绩
学生选课、退选、查询成绩、修改密码只能操作自己的选课记录和成绩

从登录后进入的主界面截图能明显看出,不同角色的主窗口底部导航按钮不一样。这个设计不是靠多个独立程序实现的,而是同一个主窗体类根据传入的 role 参数动态决定显示哪些面板。这里抛出一个实现思路,也是你读源码时值得注意的地方:

// 登录成功后的角色判断逻辑 String role = (String) roleBox.getSelectedItem(); if ("admin".equals(role)) { mainFrame.showAdminPanel(); // 显示学生、课程、教师管理面板 } else if ("teacher".equals(role)) { mainFrame.showTeacherPanel(); // 显示成绩录入和课程名单面板 } else { mainFrame.showStudentPanel(); // 显示选课和个人成绩面板 }

思路是先把每种角色对应的面板做成单独方法,然后按角色开关。这个写法的好处是后续新增角色时,只需要在登录校验里加一个分支,再实现对应的 showXxxPanel。坏处是如果角色增多,mainFrame 类会膨胀。但对于课设规模,这个方案是性价比最高的。

3.3 为什么选 MySQL 8 + JDBC 而不是 MyBatis?课设场景的现实取舍

很多同学看到这是 Java 项目,第一反应是“为什么不用 MyBatis?”。答案是:Swing 是桌面程序,没有 Web 容器,引入 MyBatis 需要额外的 mybatis-config.xml 和 mapper 文件,配置复杂度反而高于直接写 JDBC。项目正文里明确写了数据库连接驱动是 mysql-connector-j-8.3.0.jar,这是纯 JDBC 方案。

课设答辩时,老师关注的重点是你的 SQL 有没有写对、事务有没有处理、连接有没有关闭,而不是框架用得多少。JDBC 的代码逻辑直白,每一行都能对着课本找到出处,反而更容易解释。另外你可能会在搜资料时看到大量“java面试题”里问 JDBC 连接池、PreparedStatement 预编译这些概念,这套系统正好能作为理解这些问题的实体案例。如果你后续想要提升,可以把它改造成接入 Druid 连接池,这在第 6 章我会给出具体改法和面试价值。

从数据库选型角度,MySQL 8 是目前课设报告最容易写“为什么选它”的答案:开源免费、跨平台、支持 SQL 标准、可通过 Navicat 可视化操作。如果你在 Linux 服务器上部署,mysql 安装和连接配置的思路也完全一样,只是安装命令不同。这套项目的核心逻辑不依赖 Windows 特性,所以跨平台迁移成本低。

4. Swing 界面与业务逻辑:选课、成绩录入和查询是怎么落地的(附关键代码)

4.1 登录与新窗口切换:JFrame 和事件监听的最小骨架

任何 Swing 应用的第一步都是 JFrame。这套系统的登录界面截图显示,它包含账号输入框、密码输入框、角色下拉框和登录按钮。登录按钮的点击事件是整个系统的入口,它的实现模式也是 Swing 事件监听的标准写法:

loginBtn.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // 1. 从输入框取值,并拼接角色 String username = usernameField.getText(); String password = new String(passwordField.getPassword()); String role = roleBox.getSelectedItem().toString(); // 2. 调用 service 层校验 boolean ok = loginService.checkLogin(username, password, role); // 3. 根据校验结果跳转或提示 if (ok) { JOptionPane.showMessageDialog(LoginFrame.this, "登录成功"); new MainFrame(role, username).setVisible(true); LoginFrame.this.dispose(); // 隐藏登录窗口 } else { JOptionPane.showMessageDialog(LoginFrame.this, "账号或密码错误,请重试"); } } });

逻辑说明:第一步从 JTextField 拿字符串,从 JPasswordField 拿密码数组。这里注意密码框不能用 getText(),因为返回的是 String 会留在内存里,用 getPassword() 拿 char[] 用完即可清空,更安全。校验方法 loginService.checkLogin 内部会执行 SQL 查询,拿用户输入的账号密码和角色去对应表里比对。登录成功后,把当前角色和用户名传给 MainFrame,再 dispose 掉登录窗口,避免关主窗体后登录页面还残留在后台。

参数说明:role 变量决定用户能看哪些功能,username 决定后续查询以谁的身份进行,比如学生查询成绩时要用 username 作为学号条件。这里有一个小细节:如果用户名和角色不匹配,checkLogin 必须返回失败,否则会出现“学生账号选了管理员角色登录成功”的问题。

4.2 学生选课:把课程列表读进 JTable,再写入选课表

学生选课界面的核心流程是:进入界面后,查询所有可选课程展示在 JTable 中,学生选中一行点击选课按钮,系统往 sc 表插入一条记录。这里最关键的是“可选课程”的 SQL 怎么写,一个合格的做法是使用 NOT IN 子查询排除已选课程:

// 查询当前学生还没选的课程 String sql = "SELECT cno, cname, credit FROM course " + "WHERE cno NOT IN (SELECT cno FROM sc WHERE sno = ?)"; PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, sno); // sno 是当前登录学生的学号 ResultSet rs = ps.executeQuery(); // 把结果集填充到 JTable 的 DefaultTableModel 里 DefaultTableModel model = (DefaultTableModel) table.getModel(); model.setRowCount(0); // 清空上一次残留的数据 while (rs.next()) { model.addRow(new Object[] { rs.getString("cno"), rs.getString("cname"), rs.getDouble("credit") }); }

逻辑说明:先定义 SQL,用 ? 占位符传学号,调用 PreparedStatement 的 setString 给占位符赋值。这里不使用 Statement 拼接字符串,是因为拼接容易导致 SQL 注入。JTable 本身不直接存数据,它依赖 TableModel,所以更新界面时先清空 model 再重新 addRow。

参数说明:sno 是登录时保存的学生号,从登录窗口一路传过来。如果该学生在 sc 表里没有选课记录,NOT IN 子查询返回空集合,所有课程都会显示。选课按钮的监听器逻辑同理,做 INSERT:

String insertSql = "INSERT INTO sc(sno, cno) VALUES(?, ?)"; PreparedStatement ps = conn.prepareStatement(insertSql); ps.setString(1, sno); ps.setString(2, selectedCno); int rows = ps.executeUpdate(); if (rows > 0) { JOptionPane.showMessageDialog(this, "选课成功"); // 重新加载课程列表 loadAvailableCourses(); }

这里有个业务细节:选课表 sc 的 score 字段在插入时没有赋值,默认 NULL,表示未考试。到成绩录入阶段,教师端执行 UPDATE 而不是 INSERT。这也呼应了第 3 章的表结构设计——成绩是选课行为的后续状态变更,不是独立实体。如果你在实现时误用了 INSERT 覆盖成绩,会导致一个学生同一门课出现多条记录,这是课设答辩时很容易被挑出的逻辑错误。

4.3 成绩录入和查询:一条 update 和一个 join 查询

成绩录入界面里的 JTable 会先展示当前教师所授课程的选课学生名单,教师直接在表格里填分或通过弹窗输入分数。保存的 SQL 事务性很强,一般是一句 UPDATE:

String updateSql = "UPDATE sc SET score = ? WHERE sno = ? AND cno = ?"; PreparedStatement ps = conn.prepareStatement(updateSql); ps.setDouble(1, 85.5); // 要录入的成绩 ps.setString(2, sno); // 学号 ps.setString(3, cno); // 课程号 int rows = ps.executeUpdate(); if (rows == 0) { // 如果影响行数为 0,说明该学生没选这门课 JOptionPane.showMessageDialog(this, "该学生未选这门课程"); }

成绩查询的界面则是一个典型的三表联合查询。学生查询成绩时,JTable 需要展示课程名、学分、成绩三列,数据来自 course 和 sc 两张表的关联:

String querySql = "SELECT c.cname, c.credit, sc.score FROM course c " + "JOIN sc ON c.cno = sc.cno WHERE sc.sno = ?"; PreparedStatement ps = conn.prepareStatement(querySql); ps.setString(1, sno); ResultSet rs = ps.executeQuery(); // 遍历 rs,把每行数据塞进 JTable while (rs.next()) { String cname = rs.getString("cname"); int credit = rs.getInt("credit"); Double score = rs.getDouble("score"); if (rs.wasNull()) { score = null; // 尚未录入成绩,显示“未考” } model.addRow(new Object[]{cname, credit, score}); }

这段代码里的 rs.getDouble 必须在取值后立刻调用 wasNull 判断,否则把 NULL 转成 double 会返回 0.0,用户看到“0 分”就会误以为自己挂了科。这是 JDBC 里结果集空值处理的经典坑,也面试里常考的点:ResultSet 的 getXxx 方法如何感知 NULL 值。

换句话说,整个系统的核心就三条 SQL:选课查 NOT IN、录入成绩 UPDATE、成绩查询 JOIN。把这三种 SQL 的写法吃透,再去理解复杂的教务系统也不难。

5. 避坑指南:连接、编码、界面显示绕不过去的五个问题

5.1 连接与驱动类问题

这一节内容我从自己的调试记录里挑了三项,都是拿到这套系统后最容易踩的。

现象一:运行项目后窗口还没弹出,控制台报 SQLNonTransientConnectionException 或 Communications link failure。原因:MySQL 驱动与数据库之间的 SSL 握手失败。MySQL 8 默认开启 SSL,驱动 8.x 也会默认尝试 SSL 连接,本地库通常没有配置有效证书。解决:在 JdbcConfig 的连接 URL 上加 useSSL=false,同时加 allowPublicKeyRetrieval=true,这也对应了网络检索里常看到的 mysql ssl 连接错误:

jdbc:mysql://localhost:3306/stusystem?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Shanghai

现象二:报错信息是 java.sql.SQLException: The server time zone value '�й���׼ʱ��' is unrecognized。原因:MySQL 8 的时区配置没有显式指定,而驱动要求提供 serverTimezone。解决:在 URL 中加 serverTimezone=Asia/Shanghai。如果你拿到的源码里没写这个参数,补上即可。时区参数一旦缺失,同学借脚本跑别人电脑上时经常出现,属于典型的“同一份代码在不同机器上结果不同”的坑。

现象三:用 Navicat 能连上 MySQL,但程序报 Public Key Retrieval is not allowed。原因:MySQL 8 默认的 caching_sha2_password 认证插件要求客户端允许获取服务端公钥。解决:除了在 URL 加 allowPublicKeyRetrieval=true,还可以把数据库账号的认证插件改成 mysql_native_password,但改插件会影响其他客户端连接,我一般更倾向改 URL 参数,不动数据库配置。

5.2 数据与界面显示类问题

现象四:数据库表中中文显示正常,但 Swing 界面上的中文变成乱码或方块。原因有两种可能:第一是 SQL 脚本导入时使用的字符集和程序读取时不一致,比如脚本是 utf8,但导入时 Navicat 默认用了 gbk;第二是 IDEA 运行环境的文件编码没设成 UTF-8。解决:先看 SQL 脚本头部有没有 SET NAMES utf8mb4,再通过 Navicat 的连接属性里把编码设为 utf8mb4;IDEA 里在 Help > Edit Custom VM Options 加上 -Dfile.encoding=UTF-8,然后在 File > Settings > Editor > File Encodings 把项目编码和 Default encoding 都改成 UTF-8。重启 IDEA 后重新编译,中文基本能恢复。如果界面仍乱码,还要检查操作系统区域语言是否开了 Beta 版 UTF-8 选项。

现象五:按截图里的界面预览一切正常,但自己电脑上窗口显示不全,按钮错位甚至挤成一团。原因:Swing 默认布局管理器在实际运行中受屏幕分辨率和 DPI 缩放影响。作者截图时用的分辨率可能和你不同。解决:如果你只是课设交付,优先把显示器缩放调成 100% 再运行;如果想彻底改善,用 GridBagLayout 替换掉绝对定位布局,或者在 JFrame 创建时调用 setPreferredSize 控制组件尺寸。

还有一条看似玄学但影响很大:JdbcConfig 里连接 URL 中的数据库名必须和 SQL 脚本里 CREATE DATABASE 的名称一字不差。大小写不一致在 Windows 上可能不报错,但在 Linux 上直接报 error 2002 (HY000) 或 Unknown database。原因就是数据库名大小写敏感。解决的方法是打开脚本确认库名,统一成小写。我一般会直接告诉学生改成和 JdbcConfig 完全一致,避免提交到不同系统后翻车。

6. 进一步改造:把课程设计升级成能写进简历的项目

这套系统最大的提升空间不在界面,而在数据访问层。当前代码用 JdbcConfig 静态方法返回 Connection,每个 DAO 里自己创建 PreparedStatement,这是课设的标准写法,但投递简历时面试官看到这种代码很容易问一句“有没有用连接池”。我一般在拿到这类源码后,会花半小时把 JDBC 层替换成 Druid 连接池,改动不大,但面试价值直接上升一个档次。

首先是替换依赖,把 lib 下的驱动留着,再加一个 druid 的 jar 包。如果你用 Maven 重构,直接在 pom.xml 里加依赖。然后新建一个 DruidConfig:

package com.service; import com.alibaba.druid.pool.DruidDataSourceFactory; import javax.sql.DataSource; import java.io.InputStream; import java.util.Properties; public class DruidConfig { private static DataSource ds; static { try { ClassLoader cl = DruidConfig.class.getClassLoader(); InputStream in = cl.getResourceAsStream("druid.properties"); Properties props = new Properties(); props.load(in); ds = DruidDataSourceFactory.createDataSource(props); } catch (Exception e) { e.printStackTrace(); } } public static Connection getConnection() throws Exception { return ds.getConnection(); } }

druid.properties 放在 src 根目录下:

driverClassName=com.mysql.cj.jdbc.Driver url=jdbc:mysql://localhost:3306/stusystem?useSSL=false&serverTimezone=Asia/Shanghai username=root password=123456 initialSize=5 maxActive=10 maxWait=3000

替换原 JdbcConfig 后,DAO 类的调用方式不用变,只是 getConnection 从连接池取连接而不是每次新建。这样的改动有两个直接好处:第一,避免频繁创建和销毁连接;第二,你可以在面试时说“我用过 Druid 连接池,通过配置文件管理数据库资源”,这是标准答案。连接池也是 java 面试题里最高频的考点之一,理解它的原理之后,你甚至可以顺手把这套系统的 DAO 层整理成可复用的模板。

我自己的习惯是拿到任何课设源码,都是先跑一遍原始版本,确保功能完整,再按“连接池 → 统一异常处理 → 日志输出”的顺序去改造,而不是一上来就重写。有一次我直接去掉 JdbcConfig 换连接池,结果因为没注意原代码在多个类里都用 Class.forName 注册驱动,导致重复注册报错。从那以后我每次改数据访问层,都会全局搜一遍 Class.forName 和 DriverManager,强制走一遍调用链再动手。希望帮到你。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 8:24:58

哪里有网站推广公司?3个关键注意事项避开坑

哪里有网站推广公司?3个关键注意事项避开坑 网站做好了没人访问,这是很多老板最头疼的事。你花几万块做站,结果上线半年,百度搜不到,流量只有个位数。这时候你才会意识到,光有网站不够,还得找推广公司。但市面上叫“网站推广”的公司太多了,从SEO优化到SEM竞价,从内容营销到外链建设,眼花缭乱。到底哪里有…

作者头像 李华
网站建设 2026/9/28 8:24:16

WordPress域名管理插件安全避坑指南5大注意事项

WordPress域名管理插件安全避坑指南5大注意事项 备案流程一头雾水,很多人还没搞懂ICP备案到底卡在哪,就急着上线网站,结果被攻击者钻了空子。别慌,今天把 WordPress域名管理插件 里的安全 注意事项 掰开了揉碎了讲,专治各种“不知道哪出错了”的疑难杂症。 威胁场景:插件成了后门入口…

作者头像 李华
网站建设 2026/9/28 8:24:12

拒绝模板丑站:2026最新精品课程网站建设碧辉腾乐实战全解

拒绝模板丑站:2026最新精品课程网站建设碧辉腾乐实战全解 还在用那种满屏弹窗、加载慢如蜗牛、手机上看字挤在一起的模板网站吗?这种站不仅丑得让人想立刻关掉,更致命的是它根本留不住用户,转化率低到让你怀疑人生。 模板网站太丑且功能僵化,已成为2026年教育培训行业获客的最大瓶颈…

作者头像 李华
网站建设 2026/9/28 8:24:09

WordPress自带注册功能多少钱能用好别被坑

WordPress自带注册功能多少钱能用好别被坑 改个需求建站公司拖一周,最后发现注册模块还是半成品,问起来才说“这个要加钱”。很多做SEO的朋友,手里攥着WordPress后台,看到“用户注册”几个字就头大:到底该用自带的,还是上插件?用自带的到底 多少钱…

作者头像 李华
网站建设 2026/9/28 8:24:01

加大整合力度网站集约建设选哪家好

3个免费工具搞定网站集约建设,避开高价陷阱 找建站公司,最怕什么?不是技术不行,是被坑高价。 很多项目经理手里拿着预算,看着市场上几万块的报价单,心里直打鼓:这钱花得值不值? 其实,只要用对方法,加大整合力度网站集约建设,根本不需要花冤枉钱。 概念速懂:什么是集约建设…

作者头像 李华
网站建设 2026/9/28 8:23:47

共格孪晶界富锂正极:47.9 mg/cm²高载量与326.7Wh/kg

TL;DR&#xff1a;厦门大学通过分步煅烧工艺在富锂层状氧化物(LRO)体相中引入共格孪晶界(CTB)&#xff0c;将传统二维层内锂通道拓展为准三维离子扩散网络&#xff0c;同步解决厚电极的离子传输受限、应力集中和晶格氧释放三大痛点。所得CTLRO正极在47.9 mg/cm超高面载量下实现…

作者头像 李华