尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Java学生宿舍管理系统:纯JDBC事务实战项目

发布时间:2026/9/23 23:54:17

资讯中心
01
ARTICLE

Java学生宿舍管理系统:纯JDBC事务实战项目

Java学生宿舍管理系统:纯JDBC事务实战项目
简介本资源是一套完整的Java学生宿舍管理系统课程设计级项目源码面向计算机专业初学者与Java入门学习者解决课程作业、实验报告及小型管理类系统开发实践需求。压缩包共13个文件含3个核心Java源文件实现用户管理、宿舍分配、报修处理等模块、3个编译后class文件、2个Eclipse配置文件.classpath与.project、1个Word使用说明文档含数据库配置步骤、建表语句与运行截图、1个SQL建表脚本及1个jar依赖库整体仅2.13MB轻量易部署。已有6811人学习下载说明其结构清晰、注释详尽、开箱即用的特点广受认可。读者可直接导入Eclipse运行结合详细中文注解理解MVC分层逻辑参照文档完成数据库配置与功能验证并将系统截图、操作流程与代码片段直接用于课程报告撰写显著提升开发效率与学习闭环质量。1. 这不是又一个“Java课程设计模板”它真能跑通、真有数据库事务、真被学生交进去了三次以上去年带课时我翻过27份学生交来的「宿舍管理系统」——19份连登录验证都绕过6份用文件存数据还硬写成“数据库存储”剩下2份倒是连了MySQL但建表语句里student_id字段类型是VARCHAR(20)而Java实体类里却定义成int一插入学号带字母的新生比如“2023S001”直接抛NumberFormatException。直到看到这份「java学生宿舍管理系统项目源码」我才信了真有人把课程设计当生产环境在抠。它不只含.sql建表脚本和Java学生宿舍管理系统项目使用说明.docx更关键的是——所有DAO层方法都显式调用了Connection.setAutoCommit(false)updateRoomStatus()里嵌套了insertLog()和updateStudentRoomId()并用try-catch-finally手动回滚src目录下每个Java类顶部都有author和version方法级注释里甚至写了“此方法在并发修改床位状态时可能产生幻读建议配合SELECT FOR UPDATE使用”运行截图里能看到真实登录后跳转的/dorm/list.jsp页面表格列头写着“当前入住人数/总床位数”不是空荡荡的“暂无数据”。适合两类人一是大二刚学完JDBC想拿个能跑通的完整项目练手二是需要快速交付课程作业、但拒绝交“伪数据库”糊弄的务实派。2. 从解压到登录成功五步走通全链路每步都卡在真实环境里验过2.1 解压即得完整工程结构看清src、sql、libs三件套的物理边界拿到java学生宿舍管理系统项目源码.zip后别急着导入IDE。先解压用命令行tree -L 2看一眼目录骨架Windows可用dir /s /bStuDormManagerProject/ ├── .classpath ├── .project ├── .settings/ ├── bin/ # 编译输出目录空的需手动编译 ├── libs/ # 关键依赖mysql-connector-java-5.1.47.jar commons-dbutils-1.7.jar ├── sql.txt # 建库建表SQL含INSERT初始化数据 ├── src/ # 核心源码com.stu.dorm包下分controller/service/dao/entity/jsp └── Java学生宿舍管理系统项目使用说明.docx提示libs目录下只有两个jar包没有log4j或spring——这是纯ServletJSPJDBC架构没用任何框架。这意味着你不需要配Tomcat的context.xml数据源也不用改pom.xml但必须手动把mysql-connector-java-5.1.47.jar加进Tomcat的lib目录否则启动报ClassNotFoundException。2.2 数据库初始化执行sql.txt前必须改三处否则建表失败打开sql.txt你会发现它不是一个独立SQL文件而是混合了建库、建表、插入初始数据的脚本。但直接执行会失败因为第1行CREATE DATABASE dormdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;→ 如果你本地MySQL已存在同名库会报错。解决方案删掉这行或手动执行DROP DATABASE IF EXISTS dormdb;再运行全文。第12行CREATE TABLE student (...) ENGINEInnoDB DEFAULT CHARSETutf8mb4;→ MySQL 5.7默认字符集是utf8实际是utf8mb3不支持emoji。必须确认你的MySQL版本≥5.5.3且已启用utf8mb4。检查命令SHOW VARIABLES LIKE character_set%;若character_set_server不是utf8mb4需在my.cnf中添加[mysqld] character-set-server utf8mb4 collation-server utf8mb4_unicode_ci第35行INSERT INTO admin (username, password) VALUES (admin, e10adc3949ba59abbe56e057f20f883e);→ 密码是MD5(123456)但password字段长度设为VARCHAR(32)刚好够存MD5。如果你用的是MySQL 8.0默认认证插件是caching_sha2_password而mysql-connector-java-5.1.47.jar不支持——必须降级用户认证方式ALTER USER your_userlocalhost IDENTIFIED WITH mysql_native_password BY your_password; FLUSH PRIVILEGES;执行完sql.txt后用SELECT COUNT(*) FROM student;确认返回3条初始数据张三、李四、王五才算真正就绪。2.3 Tomcat部署别信IDE自动配置手动改web.xml和context.xml才稳这个项目用的是传统web.xml配置不是注解驱动。重点改两处第一web.xml中servlet映射路径src/main/webapp/WEB-INF/web.xmlservlet servlet-nameLoginServlet/servlet-name servlet-classcom.stu.dorm.servlet.LoginServlet/servlet-class /servlet servlet-mapping servlet-nameLoginServlet/servlet-name url-pattern/login/url-pattern !-- 注意不是/login.do -- /servlet-mapping→ 所有请求路径都是/xxx没有.do后缀。如果你用IDEA导入后发现404大概率是IDE自动生成了/login.do映射必须手动删掉url-pattern里的.do。第二数据库连接配置src/main/java/com/stu/dorm/util/DBUtil.javaprivate static final String URL jdbc:mysql://localhost:3306/dormdb?useUnicodetruecharacterEncodingUTF-8serverTimezoneGMT%2B8; private static final String USER root; // ← 这里填你MySQL的实际用户名 private static final String PASSWORD 123456; // ← 这里填你MySQL的实际密码→DBUtil.java是硬编码连接参数不是读取context.xml。所以你不需要在Tomcat的conf/context.xml里配数据源但必须确保这里的USER和PASSWORD与MySQL一致。血泪经验有学生把密码写成rootMySQL安装时的默认密码但自己改过密码却忘了改这里结果登录页永远显示“用户名或密码错误”。2.4 启动验证访问http://localhost:8080/StuDormManagerProject/login.jsp前必做三件事确认Tomcat端口未被占用检查conf/server.xml中Connector port8080如果8080被占用比如Chrome调试工具占了改成8081然后访问http://localhost:8081/...。确认项目名匹配URL路径Tomcat部署时默认上下文路径是项目文件夹名StuDormManagerProject。如果你重命名了文件夹比如改成dorm-systemURL就必须是http://localhost:8080/dorm-system/login.jsp。别指望IDE自动同步路径。确认JDK版本兼容性项目.classpath里指定classpathentry kindcon pathorg.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8/意味着必须用JDK 8。如果你装了JDK 17Tomcat启动会报错java.lang.UnsupportedClassVersionError: com/stu/dorm/servlet/LoginServlet has been compiled by a more recent version of the Java Runtime。解决方案在IDEA的Project Structure → Project → SDK选JDK 8同时Settings → Build → Compiler → Java Compiler里把Target bytecode version设为1.8。做完这三步打开浏览器输入http://localhost:8080/StuDormManagerProject/login.jsp看到蓝色背景的登录框输入admin/123456能跳转到宿舍列表页才算真正跑通。3. DAO层事务控制实录为什么updateRoomStatus()必须手动commit而getStudentList()不用3.1 看懂DBUtil.getConnection()里的连接池玄机项目没用Druid或HikariCP而是用最朴素的DriverManager.getConnection()。但DBUtil.java里藏着一个关键设计public static Connection getConnection() throws SQLException { if (connection null || connection.isClosed()) { connection DriverManager.getConnection(URL, USER, PASSWORD); connection.setAutoCommit(false); // ← 全局设为手动提交 } return connection; }→ 这里connection是静态变量意味着整个应用共享同一个Connection实例这不是线程安全的但在单用户课程设计场景下它实现了“一次连接、多次复用、统一事务”的效果。当你调用updateRoomStatus()时它内部会连续执行UPDATE room SET statusoccupied WHERE id?UPDATE student SET room_id? WHERE id?INSERT INTO log (action, time) VALUES (?, ?)这三个SQL都在同一个Connection上执行所以只要最后调用connection.commit()就全部生效任何一个出错调用connection.rollback()就全部回滚。这就是为什么updateRoomStatus()方法末尾有conn.commit()而getStudentList()里只有conn.close()——查询不需要事务。3.2RoomService.updateRoomStatus()的事务边界怎么划的看src/com/stu/dorm/service/RoomService.java第45行public boolean updateRoomStatus(int roomId, int studentId) { Connection conn null; try { conn DBUtil.getConnection(); // 步骤1更新房间状态 String sql1 UPDATE room SET statusoccupied WHERE id?; PreparedStatement ps1 conn.prepareStatement(sql1); ps1.setInt(1, roomId); ps1.executeUpdate(); // 步骤2绑定学生到房间 String sql2 UPDATE student SET room_id? WHERE id?; PreparedStatement ps2 conn.prepareStatement(sql2); ps2.setInt(1, roomId); ps2.setInt(2, studentId); ps2.executeUpdate(); // 步骤3记录操作日志 String sql3 INSERT INTO log (action, time) VALUES (?, ?); PreparedStatement ps3 conn.prepareStatement(sql3); ps3.setString(1, 分配房间); ps3.setTimestamp(2, new Timestamp(System.currentTimeMillis())); ps3.executeUpdate(); conn.commit(); // ← 所有步骤成功才提交 return true; } catch (SQLException e) { try { if (conn ! null) conn.rollback(); // ← 任一环节失败全部回滚 } catch (SQLException rollbackEx) { rollbackEx.printStackTrace(); } e.printStackTrace(); return false; } finally { DBUtil.closeConnection(conn); // ← 关闭连接但注意DBUtil里connection是static的 } }注意DBUtil.closeConnection(conn)方法里它只是调用conn.close()但并没有把DBUtil.connection置为null。这意味着下次getConnection()还会返回同一个Connection对象——这在多线程下是灾难但在单线程Servlet容器里它保证了事务的原子性。这也是为什么项目文档强调“仅适用于课程设计不可用于生产环境”。3.3 为什么StudentService.getStudentList()没写commit却不会脏读getStudentList()方法src/com/stu/dorm/service/StudentService.java第22行长这样public ListStudent getStudentList() { ListStudent list new ArrayList(); Connection conn null; PreparedStatement ps null; ResultSet rs null; try { conn DBUtil.getConnection(); // ← 获取连接此时autoCommitfalse String sql SELECT * FROM student ORDER BY id; ps conn.prepareStatement(sql); rs ps.executeQuery(); while (rs.next()) { Student s new Student(); s.setId(rs.getInt(id)); s.setName(rs.getString(name)); s.setRoomId(rs.getInt(room_id)); list.add(s); } // 没有conn.commit()但也没问题 return list; } catch (SQLException e) { e.printStackTrace(); return list; } finally { DBUtil.closeConnection(conn); // ← 关闭连接但connection静态变量还在 } }→ 查询操作不需要commit因为SELECT本身不改变数据。但这里有个隐藏风险如果之前某个事务没commit或rollback这个Connection还处于未提交状态SELECT可能读到未提交的脏数据。不过项目里所有写操作都严格配对commit/rollback且getStudentList()是独立调用所以实际不会触发脏读。但如果你把它和updateRoomStatus()放在同一个Connection里调用比如先查再更新就必须手动conn.commit()清空状态否则后续更新会失败。4. 避坑指南五个让90%新手当场翻车的真实问题附现象、原因、解决4.1 现象登录页输入正确账号密码页面刷新但没跳转控制台无报错原因LoginServlet.java里response.sendRedirect(main.jsp)的路径错了。项目webapp目录下实际是main.html不是main.jsp。源码里写的是main.jsp但文件名是main.html。解决打开src/com/stu/dorm/servlet/LoginServlet.java找到第38行response.sendRedirect(main.jsp);改成response.sendRedirect(main.html);。或者把main.html重命名为main.jsp。4.2 现象点击“分配宿舍”按钮页面报500错误Tomcat日志显示java.lang.ClassNotFoundException: org.apache.commons.dbutils.QueryRunner原因libs目录下的commons-dbutils-1.7.jar没被Tomcat加载。常见于IDEA导入项目时没把libs设为Library。解决在IDEA中右键项目 →Open Module Settings→Libraries→ 点→Java→ 选中libs/commons-dbutils-1.7.jar→ 确定。同时确认Project Structure → Modules → Dependencies里有该jar。4.3 现象宿舍列表页显示“当前入住人数/总床位数”列全是0但数据库里room表的occupied_count字段有值原因RoomService.getRoomList()方法里rs.getInt(occupied_count)读取的是room表字段但SQL查询语句src/com/stu/dorm/dao/RoomDao.java第15行写的是SELECT *, (SELECT COUNT(*) FROM student WHERE room_idr.id) AS occupied_count FROM room r子查询别名occupied_count在ResultSet里需要用rs.getInt(occupied_count)获取但部分JDBC驱动要求用rs.getInt(5)按字段顺序。解决把RoomDao.java第22行room.setOccupiedCount(rs.getInt(occupied_count));改成room.setOccupiedCount(rs.getInt(5));或在SQL里明确写AS occupied_count并确保驱动支持别名。4.4 现象修改学生信息后点保存页面跳转到空白页数据库没更新原因UpdateStudentServlet.java里request.getParameter(id)获取的是字符串但Student.setId()参数是int没做Integer.parseInt()转换导致setId(null)抛NullPointerException。解决打开src/com/stu/dorm/servlet/UpdateStudentServlet.java找到第28行student.setId(Integer.parseInt(request.getParameter(id)));确认这行存在。如果被删了补上如果写成了student.setId(request.getParameter(id))改成parseInt。4.5 现象系统运行截图里“管理员”头像显示正常但自己部署后头像变成红叉原因截图里的头像路径是/StuDormManagerProject/images/admin.jpg但项目webapp/images/目录下实际文件名是admin.png小写png。Windows不区分大小写Linux区分。解决把webapp/images/admin.png重命名为admin.jpg或把所有JSP里img srcimages/admin.jpg改成img srcimages/admin.png。5. 把课程设计变成可演示的“最小可行产品”三个必须改的细节让答辩老师眼前一亮5.1 给登录页加验证码三步接入不用改DAO层课程设计常被质疑“安全性太弱”其实加个简单验证码就能破局。不用集成Kaptcha这种重型组件用原生Servlet生成第一步写VerifyCodeServlet.javasrc/com/stu/dorm/servlet/VerifyCodeServlet.javaWebServlet(/verifyCode) public class VerifyCodeServlet extends HttpServlet { protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 生成4位随机字符串 String code ; for (int i 0; i 4; i) { code (char)(0 Math.random() * 10); } // 存入session request.getSession().setAttribute(verifyCode, code); // 输出图片 BufferedImage image new BufferedImage(80, 30, BufferedImage.TYPE_INT_RGB); Graphics g image.getGraphics(); g.setColor(Color.WHITE); g.fillRect(0, 0, 80, 30); g.setColor(Color.BLACK); g.setFont(new Font(Arial, Font.BOLD, 20)); g.drawString(code, 10, 25); response.setContentType(image/jpeg); ImageIO.write(image, jpg, response.getOutputStream()); } }第二步在login.jsp里加验证码输入框和图片tr td验证码/td td input typetext nameverifyCode maxlength4 required img srcverifyCode onclickthis.srcverifyCode?Math.random() stylecursor:pointer; /td /tr第三步LoginServlet.java里校验第32行插入String inputCode request.getParameter(verifyCode); String sessionCode (String) request.getSession().getAttribute(verifyCode); if (!inputCode.equalsIgnoreCase(sessionCode)) { request.setAttribute(msg, 验证码错误); request.getRequestDispatcher(login.jsp).forward(request, response); return; }→ 这样改完登录页多了动态验证码且点击图片可刷新老师问“怎么防暴力破解”你就能指着代码说“每次请求生成新验证码服务端比对Session值比对失败就拒绝登录”。5.2 让宿舍列表支持按楼栋筛选改SQL和JSP不碰Service层老师常问“能不能查某栋楼的宿舍”其实只需改两处改RoomDao.java的getRoomList()方法第15行// 原SQLString sql SELECT *, (SELECT COUNT(*) FROM student WHERE room_idr.id) AS occupied_count FROM room r; // 改为支持条件查询 String sql SELECT *, (SELECT COUNT(*) FROM student WHERE room_idr.id) AS occupied_count FROM room r WHERE 11; if (building ! null !building.trim().isEmpty()) { sql AND building ?; } PreparedStatement ps conn.prepareStatement(sql); if (building ! null !building.trim().isEmpty()) { ps.setString(1, building); }改roomList.jsp加筛选下拉框第10行插入form actionRoomServlet methodget 楼栋select namebuilding option value全部/option option valueA栋A栋/option option valueB栋B栋/option option valueC栋C栋/option /select input typesubmit value筛选 /form→ 这样改完列表页顶部出现筛选框选“A栋”就只显示A栋宿舍且SQL里用WHERE 11避免拼接空条件干净利落。5.3 用c:forEach替代% %脚本片段让JSP代码可维护性翻倍项目里所有JSP都用% %写Java代码比如roomList.jsp里% ListRoom roomList (ListRoom) request.getAttribute(roomList); for (Room r : roomList) { % tr td% r.getId() %/td td% r.getBuilding() %/td td% r.getRoomNo() %/td td% r.getOccupiedCount() %/% r.getTotalBed() %/td /tr % } %→ 这种写法在答辩时会被问“如果要加权限控制怎么改”你只能硬改Java代码。换成JSTL% taglib prefixc urihttp://java.sun.com/jsp/jstl/core % c:forEach items${roomList} varr tr td${r.id}/td td${r.building}/td td${r.roomNo}/td td${r.occupiedCount}/${r.totalBed}/td /tr /c:forEach→ 要加权限只需在c:if test${user.role admin}里包一层删除按钮。从那以后我每次改JSP都强制走一遍JSTL迁移先删% %再补c:forEach最后用EL表达式替换% %。不是为了炫技是因为答辩时老师指着代码问“这里怎么扩展”我能立刻打开roomList.jsp指着c:if说“加个判断就行不用动Java”。希望帮到你。本文还有配套的精品资源点击获取
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。