ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Java+MySQL学生信息管理系统源码解析:JDBC增删改查与Swing实战

Java+MySQL学生信息管理系统源码解析:JDBC增删改查与Swing实战 简介这份资源面向Java初学者与需要完成课程设计的学生提供一套基于Java Swing与MySQL的学生信息管理系统实现方案重点解决使用JDBC完成学生信息增删改查的典型课设需求。压缩包内共1个PDF文件大小约135KB以图文形式呈现项目源码与数据库设计涵盖建库建表语句、model-dao-view分层结构以及管理员、学生实体类的定义便于读者理解各模块职责与代码组织方式。资源中给出了admin与student两张表的完整SQL包含学号、姓名、院系、籍贯、学分、邮箱、联系方式等字段并附有示例数据可直接用于本地环境搭建与调试。目前已有5010人学习下载适合作为Java数据库编程入门、Swing界面开发练习及课程设计参考帮助读者快速掌握JDBC操作与分层开发思路。1. 从一份 2016 年的课设源码说起JavaMySQL 学生信息管理系统到底能跑出什么如果你正在搜「Java学生信息管理系统源码」「Java课程设计案例源码」大概率是课设 deadline 逼近或者想找一个能跑通 JDBC 增删改查的最小闭环项目练手。这份基于 Java Swing MySQL 的学生信息管理系统开发环境是 jdk7 MySQL5 win7代码结构走的是经典的 model-dao-view 三层核心就是用 JDBC 把学生信息的增删改查串起来再套一层 Swing 界面。它不花哨没有 Spring、没有 MyBatis但正因为「裸奔」反而适合拿来理解 JDBC 到底怎么连库、DAO 怎么封装、Swing 表格怎么和数据库联动。适合谁一是课设需要交差、想快速拿到可运行源码的同学二是刚学完 Java 基础、想找一个完整 CRUD 项目把面向对象编程 Java 的封装、继承、多态落地一遍的人。下面我按「拿到源码怎么跑起来 → 每层代码在干什么 → 容易翻车的地方 → 怎么把它改得更像样」的顺序拆一遍。2. 把源码跑起来建库建表、导依赖、改配置三步走2.1 先建库建表别急着打开 IDE很多人拿到源码第一反应是直接 import 进 IntelliJ IDEA 然后点运行结果控制台一片红。血泪经验是先把数据库准备好再动代码。这份项目的建库建表语句在正文里给全了直接复制到 Navicat for MySQL 或者命令行里执行即可。注意admin表里预置了一条admin/admin/admin的记录这是登录用的别删。-- 建库 CREATE DATABASE student DEFAULT CHARSETutf8; -- 管理员表 DROP TABLE IF EXISTS admin; CREATE TABLE admin ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(20) NOT NULL, username varchar(20) NOT NULL, password varchar(20) NOT NULL, PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT2 DEFAULT CHARSETutf8; INSERT INTO admin VALUES (1,admin,admin,admin); -- 学生表 DROP TABLE IF EXISTS student; CREATE TABLE student ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(20) NOT NULL, sno varchar(20) NOT NULL, department varchar(20) NOT NULL, hometown varchar(20) NOT NULL, mark varchar(20) NOT NULL, email varchar(20) NOT NULL, tel varchar(20) NOT NULL, sex varchar(20) NOT NULL, PRIMARY KEY (id) ) ENGINEInnoDB AUTO_INCREMENT22 DEFAULT CHARSETutf8; INSERT INTO student VALUES (18,张三,001,信息科学技术学院,辽宁,80,zhangsan163.com,13888888888,男), (19,李四,002,理学院,上海,70,lisisina.com,13812341234,男), (20,王五,003,外国语学院,北京,88,wangwu126.com,13698765432,女);这段 SQL 的逻辑很直白admin表只管登录student表存学生全字段。参数上要注意sno是学号虽然设了varchar(20)但没加唯一索引这意味着数据库层面不拦重复学号重复校验得靠 DAO 里的queryBySno手动做——这是后面避坑章节要重点说的点。字符集统一utf8如果你本地 MySQL 是 8.0 且默认utf8mb4插中文一般没问题但连接串里的编码参数别写错。2.2 导入项目与依赖JDBC 驱动是唯一的硬依赖项目本身没有 Maven 的pom.xml2016 年的课设风格所以依赖得手动加。唯一必须的 jar 是 MySQL 的 JDBC 驱动也就是mysql-connector-java。在 IntelliJ IDEA 里操作路径是File → Project Structure → Libraries → 加号 → 选中你下载的mysql-connector-java-5.x.jar。版本要和你的 MySQL 对上MySQL 5.x 配5.1.x的驱动MySQL 8.x 则要用8.0.x驱动否则会撞上this version of the jdbc driver is only compatible with...这类版本不匹配报错。# 如果用命令行编译运行classpath 要带上驱动 javac -encoding UTF-8 -cp .;mysql-connector-java-5.1.49.jar com/student/**/*.java java -cp .;mysql-connector-java-5.1.49.jar com.student.view.LoginViewWindows 下 classpath 分隔符是分号;Linux/Mac 是冒号:这点搞错会直接报ClassNotFoundException。另外源码里用了Class.forName(AppConstants.JDBC_DRIVER)这种老式加载驱动写法MySQL 8 驱动类名变成了com.mysql.cj.jdbc.Driver连接串也要加时区和 SSL 参数否则会报mysql ssl连接错误或者时区异常。2.3 改 AppConstants连接串、账号、密码三处对齐项目把数据库配置抽到了AppConstants里这是好习惯改一处就行。你需要确认四个常量JDBC_DRIVER、JDBC_URL、JDBC_USERNAME、JDBC_PASSWORD。URL 的典型写法是jdbc:mysql://localhost:3306/student?useUnicodetruecharacterEncodingutf8。如果你本地 MySQL 8建议改成public static final String JDBC_DRIVER com.mysql.cj.jdbc.Driver; public static final String JDBC_URL jdbc:mysql://localhost:3306/student?useUnicodetruecharacterEncodingutf8serverTimezoneAsia/ShanghaiuseSSLfalse; public static final String JDBC_USERNAME root; public static final String JDBC_PASSWORD 你的密码;serverTimezone不加MySQL 8 会直接抛时区异常useSSLfalse是本地开发图省事生产环境别这么干。改完这三处运行LoginView用admin/admin登录能进主界面看到学生列表就说明整条链路通了。3. model-dao-view 三层拆解JDBC 增删改查是怎么被封装起来的3.1 model 层两个 POJO 撑起数据载体Admin和Student两个类就是标准的 POJO私有字段加 getter/setter。Student有 9 个字段id、sno、name、sex、department、homeTown、mark、email、tel。注意mark学分用的是String而不是int这是这份源码一个偷懒的地方——数据库里也是varchar(20)。好处是省去了类型转换坏处是你没法在数据库层做数值排序和统计。如果你要按学分排序得在 Java 里转Integer.parseInt还得处理空值和非法字符。面向对象编程 Java 里 POJO 的职责就是承载数据不掺业务逻辑这一点它做到了。3.2 DBUtil单例 PreparedStatement 的 JDBC 封装DBUtil是整个项目的黑匣子把 JDBC 的重复代码收拢了。它用饿汉式单例getDBUtil保证全局一个实例内部持有Connection、PreparedStatement、ResultSet。核心方法就四个两个executeUpdate带参和不带参、两个executeQuery带参和不带参。带参版本用Object[]接收参数循环ps.setObject(i1, obj[i])填充占位符——这就是jdbc增删改查里防 SQL 注入的标准姿势。public int executeUpdate(String sql, Object[] obj) { int result -1; if (getConn() null) return result; try { ps conn.prepareStatement(sql); for (int i 0; i obj.length; i) { ps.setObject(i 1, obj[i]); // 占位符从 1 开始 } result ps.executeUpdate(); close(); // 注意这里更新完就关了连接 } catch (SQLException e) { e.printStackTrace(); } return result; }参数说明sql是带?的预编译语句obj是按顺序对应的参数数组。这里有个细节坑——executeUpdate带参版本执行完直接调了close()把连接也关了而executeQuery带参版本没关留给调用方在destroy()里关。这种不对称设计容易让新手困惑后面避坑章节细说。getConn()里做了懒加载连接为空或已关闭才重新DriverManager.getConnection算是简易的连接复用。3.3 DAO 层BaseDAO 工厂 两个具体 DAOBaseDAO是个抽象类用getAbilityDAO(DAO dao)这个静态工厂方法根据枚举返回AdminDAO或StudentDAO单例。它持有protected final DBUtil db子类直接用。destroy()方法负责关ResultSet和连接。AdminDAO只有一个queryForLogin用select * from admin where username? and password?判断登录返回 boolean。StudentDAO是重头戏五个方法add、delete、update、queryByName、list。add方法先调queryBySno查学号是否存在存在就返回 false不存在才 insert。update同样先校验学号存在再用update student set ... where name? and sno?更新。delete用name sno双条件删除。list方法做分页showNum15用limit ?,?实现beginNum (pageNum-1)*showNum。queryByName用like %name%模糊查。所有查询结果最终被buildList塞进ListStudent再由buildResult转成String[][]二维数组给 Swing 表格用。// 分页查询核心 int beginNum (pageNum - 1) * showNum; String sql select * from student limit ?,?; Integer[] param { beginNum, showNum }; rs db.executeQuery(sql, param);参数说明pageNum从 1 开始showNum固定 15。limit的第一个参数是偏移量第二个是条数。这里用Integer[]而不是String[]因为setObject能识别 Integer 类型MySQL 的 limit 也接受整型。注意buildList里stu.setId(i1)是重新编的序号不是数据库真实 id这会导致删除时如果按界面显示的 id 去操作会对不上——这是个隐藏坑。3.4 view 层Swing 表格 事件监听串起交互MainView继承JFrame北边放搜索框和按钮中间放JTable南边放分页按钮。表格列由String[] column定义数据来自StudentDAO.list(currPageNum)返回的二维数组。搜索框绑了KeyListener回车触发FindListener调queryByName。分页按钮控制currPageNum增减再重新list刷新表格。AddView、DeleteView、UpdateView是三个独立窗口分别调StudentDAO的add、delete、update。整个 view 层就是「收集用户输入 → 调 DAO → 刷新表格」的循环没有 MVC 框架纯手写事件驱动。4. 避坑与排查这份源码跑不通的五个高频原因4.1 现象登录报 ClassNotFoundException驱动找不到原因JDBC 驱动 jar 没加进 classpath或者 IDEA 里加了但没勾选到模块的 dependencies。解决Project Structure → Modules → Dependencies 确认驱动在列表里且 scope 是 Compile命令行运行则确认-cp里带了 jar 的完整路径。MySQL 8 还要确认驱动类名是com.mysql.cj.jdbc.Driver而不是老的com.mysql.jdbc.Driver。4.2 现象插入中文变问号或乱码原因数据库、表、连接串三处字符集不一致。解决建库建表用utf8或utf8mb4连接串加useUnicodetruecharacterEncodingutf8IDEA 的 File Encoding 设成 UTF-8。如果 MySQL 是 8.0 且表是utf8mb4连接串的characterEncoding也建议写utf8驱动会映射别写utf8mb4有些老驱动不认。4.3 现象更新或删除后再查询报连接已关闭原因DBUtil.executeUpdate带参版本执行完直接close()关了连接而StudentDAO.update里在db.executeUpdate之后又调了destroy()destroy里再关一次。虽然close()对已关闭连接通常不抛异常但如果中间又穿插了别的查询就会撞上Connection is closed。解决统一关闭策略要么 DBUtil 不关、由 DAO 的destroy统一关要么 DBUtil 关、DAO 不再重复关。我一般会把executeUpdate里的close()去掉交给destroy()收尾。4.4 现象学号重复插入没被拦住原因student表的sno字段没有唯一约束queryBySno的校验存在并发窗口——两个请求同时查都说不存在然后都插入。课设单机跑一般碰不到但如果你拿它当模板做正式点的东西这就是隐患。解决给sno加UNIQUE索引数据库层兜底DAO 层的校验作为友好提示保留。4.5 现象分页翻到最后一页后继续点「下一页」表格空白原因MainView里maxPageNum写死 99但实际数据可能只有 3 条currPageNum超过真实页数时list返回 null表格被清空。解决在list返回 null 时保持当前页不变或者先查count(*)算出真实总页数再限制翻页范围。常见做法是加一个getTotalCount方法maxPageNum (total showNum - 1) / showNum。5. 进阶改造从「能跑」到「像样」的三个具体动作5.1 把 mark 改成 int 并加校验mark用 String 存是这份源码最别扭的地方。改造步骤数据库ALTER TABLE student MODIFY mark int(11)Student类字段改private int markAddView和UpdateView里输入框取值时用Integer.parseInt并 try-catch 处理非数字。这样list方法就能支持按学分排序SQL 加order by mark desc即可。注意历史数据里如果有非数字的 mark改字段前先清洗。5.2 用连接池替掉手写单例连接DBUtil每次getConn都新建连接频繁增删改查下性能很差。常见做法是引入 Druid 或 HikariCP把DriverManager.getConnection换成dataSource.getConnection()。以 HikariCP 为例HikariConfig config new HikariConfig(); config.setJdbcUrl(AppConstants.JDBC_URL); config.setUsername(AppConstants.JDBC_USERNAME); config.setPassword(AppConstants.JDBC_PASSWORD); config.setMaximumPoolSize(10); HikariDataSource ds new HikariDataSource(config); // 之后 conn ds.getConnection();参数说明maximumPoolSize按并发量调课设 10 足够连接用完必须close()归还池子而不是真关。改造后DBUtil的getConn和close逻辑要相应调整close变成归还连接。5.3 给表格加真实 id 隐藏列修掉删除错位前面说过buildList里setId(i1)是假 id导致界面显示的行号和数据库真实 id 脱节。改造方法buildList里改成stu.setId(rs.getInt(id))buildResult第一列仍放 id 但界面上可以把这一列隐藏jTable.getColumnModel().getColumn(0).setMinWidth(0)之类删除和更新时从选中行拿到真实 id 去操作。这样delete的 SQL 就可以简化成delete from student where id?比name sno双条件可靠得多——毕竟重名重学号的极端情况虽然少但真碰上就是删错人的事故。从那以后我每次拿到这种课设级源码都强制先跑一遍「建库 → 改配置 → 登录 → 增删改查 → 翻页」五步冒烟测试再动任何一行代码。这份 JavaMySQL 学生信息管理系统源码结构清晰、依赖极简作为 JDBC 和 Swing 的练手底子完全够用但上面这些坑你得心里有数。希望帮到你。本文还有配套的精品资源点击获取
返回列表