恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
Java Web员工管理系统实战:Tomcat+MySQL可部署源码
首页
资讯中心
/
Java Web员工管理系统实战:Tomcat+MySQL可部署源码
Java Web员工管理系统实战:Tomcat+MySQL可部署源码
发布时间:2026/10/7 12:39:53
简介这是一套面向Java Web初学者与进阶开发者的员工管理系统实战源码资源聚焦Servlet、JSP、JDBC及MVC分层架构的综合应用帮助开发者掌握企业级Web应用从数据库设计到前后端交互的完整开发流程。压缩包共246个文件含50个核心Java源文件如Emploe.class、DeptDaoImpl.class等、28个JSP页面实现员工信息展示与管理界面、102个编译后Class文件、26个PNG与11个JPG资源图以及SQL建库脚本、web.xml配置、JDBC连接属性等关键支撑文件整体大小仅2.45MB轻量易部署。已有1086人学习下载资源结构清晰src目录组织业务逻辑与DAO层WebContent承载视图与静态资源database提供可直接导入的MySQL脚本配合.classpath与.project文件开箱即用于Eclipse环境。读者可借此深入理解CRUD实现细节、请求响应流程、分层解耦设计并快速复现一个功能完备的后台管理系统。1. 这不是“又一个Java Web练手项目”它是一份能跑在Tomcat 8.5、MySQL 5.7上的真实业务骨架含完整CRUD链路、角色权限雏形与可调试SQL日志你搜“java web员工管理系统 源码 数据库”点开十几个压缩包90%解压后连web.xml都缺半截或者jdbc.properties里写着localhost:3306/empdb却没建库脚本更别提Hibernate映射错位、JSP中文乱码、Servlet路径404——这不是教学Demo是踩过生产环境部署坑的工程师打包出来的最小可行闭环。这个.zip包里真正值钱的不是那200行EmployeeServlet.java而是sql/emp_init.sql里带注释的建表语句、src/main/webapp/WEB-INF/web.xml中明确标注load-on-startup1/load-on-startup的初始化监听器、以及log4j.properties里把org.hibernate.SQL设为DEBUG级的日志开关。它不教你怎么写冒泡排序但教你如何让/employee/list接口返回JSON时避开Jackson序列化空指针、如何用WebServlet(/employee/delete)替代XML配置避免路径冲突、为什么mysql-connector-java-5.1.47.jar必须放在WEB-INF/lib而非全局classpath。适合刚学完Servlet/JSP想验证知识闭环的新人也适合需要快速搭后台管理原型的外包开发者——只要你的目标是“今天下午把员工列表页面挂到测试服务器上”而不是“理解MVC三层解耦的哲学意义”。2. 从解压到启动三步跑通本地环境含Tomcat 9兼容性补丁2.1 解压结构解析认准这5个关键目录跳过所有“教程文档”文件夹拿到java web员工管理系统(源码数据库).zip后先别急着导入IDE。用命令行或资源管理器直接解压观察顶层目录结构。真正需要关注的只有以下5个路径其他如doc/、readme.txt、截图/可延后看├── src/ # Java源码根目录含servlet、dao、entity ├── WebContent/ # 传统Dynamic Web Project的Web根目录注意不是src/main/webapp │ ├── WEB-INF/ │ │ ├── web.xml # 核心配置重点看servlet-mapping和filter │ │ └── lib/ # JAR包存放处确认有mysql-connector-java-*.jar │ ├── employee/ # JSP页面目录list.jsp, add.jsp等 │ └── css/js/images/ # 静态资源 ├── sql/ # 数据库脚本emp_init.sql必执行 ├── build.xml # Ant构建脚本非Maven注意 └── README.md # 通常只有一行“请先执行sql/emp_init.sql”提示如果解压后看到pom.xml说明此包被二次改造过原生是Ant构建此时需忽略build.xml改用Maven命令若无pom.xml则严格按Ant流程走。本包默认无pom.xml后续所有操作基于Ant。2.2 数据库初始化用emp_init.sql建库建表绕过字符集玄学不要手动在MySQL里敲CREATE DATABASE。直接执行sql/emp_init.sql——这是本包最稳的建库方式。该SQL文件通常包含三段关键逻辑-- 1. 创建数据库并指定字符集关键 CREATE DATABASE IF NOT EXISTS empdb CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; -- 2. 切换数据库 USE empdb; -- 3. 建表语句含外键约束注意ENGINEInnoDB CREATE TABLE employee ( id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50) NOT NULL, gender ENUM(男,女) DEFAULT 男, department VARCHAR(100), salary DECIMAL(10,2), hire_date DATE ) ENGINEInnoDB DEFAULT CHARSETutf8mb4;执行命令Linux/macOSmysql -u root -p sql/emp_init.sqlWindows用户可用Navicat或MySQL Workbench右键执行SQL文件。重点检查执行后是否出现Query OK, 0 rows affected建库成功和Query OK, 0 rows affected建表成功进入MySQL执行SHOW CREATE TABLE employee;确认DEFAULT CHARSETutf8mb4存在若报错Unknown character set: utf8mb4说明MySQL版本低于5.5.3降级为utf8修改SQL中所有utf8mb4为utf8但会丢失emoji支持。2.3 Tomcat部署用Ant一键打包WAR避开IDE自动部署陷阱本包使用Ant构建而非IDE内置部署。打开终端进入解压根目录执行# 确保已安装Antbrew install ant 或下载ant.apache.org ant clean # 清理旧class文件 ant compile # 编译Java源码到build/classes ant war # 打包为ROOT.war注意不是emp.warant war成功后会在根目录生成ROOT.war。不要把整个WebContent文件夹拖进Tomcatwebapps/正确做法# 停止Tomcat $TOMCAT_HOME/bin/shutdown.sh # Linux/macOS # 或双击 $TOMCAT_HOME/bin/shutdown.batWindows # 将ROOT.war复制到webapps目录 cp ROOT.war $TOMCAT_HOME/webapps/ # 启动Tomcat $TOMCAT_HOME/bin/startup.sh为什么必须用ROOT.war查看build.xml中war destfileROOT.war定义且web.xml里url-pattern//url-pattern绑定根路径。若打包成emp.war访问地址会变成http://localhost:8080/emp/employee/list而源码JSP中form actionemployee/add是相对路径会导致提交404。用ROOT.war则访问http://localhost:8080/employee/list路径完全匹配。3. 源码层关键链路拆解从HTTP请求到数据库更新的7个落地节点3.1 请求入口web.xml里的Filter链与Servlet映射真相打开WebContent/WEB-INF/web.xml找到核心配置段!-- 字符编码过滤器解决POST中文乱码 -- filter filter-nameCharacterEncodingFilter/filter-name filter-classcom.filter.CharacterEncodingFilter/filter-class init-param param-nameencoding/param-name param-valueUTF-8/param-value /init-param /filter filter-mapping filter-nameCharacterEncodingFilter/filter-name url-pattern/*/url-pattern /filter-mapping !-- 员工管理Servlet映射 -- servlet servlet-nameEmployeeServlet/servlet-name servlet-classcom.servlet.EmployeeServlet/servlet-class /servlet servlet-mapping servlet-nameEmployeeServlet/servlet-name url-pattern/employee/*/url-pattern !-- 关键通配符匹配 -- /servlet-mapping血泪经验url-pattern/employee/*/url-pattern意味着所有以/employee/开头的请求如/employee/list,/employee/delete?id1都会进入EmployeeServlet。而EmployeeServlet.java中通过request.getRequestURI()截取路径后缀来分发逻辑// com.servlet.EmployeeServlet.doGet() String path request.getRequestURI(); // 返回 /employee/list String action path.substring(path.lastIndexOf(/) 1); // 提取 list if (list.equals(action)) { listEmployees(request, response); } else if (add.equals(action)) { showAddPage(request, response); // 转发到add.jsp }参数说明request.getRequestURI()获取的是客户端请求的完整路径不含域名和查询参数lastIndexOf(/)定位最后一个/位置substring(...1)精准提取动作名。这种写法比request.getParameter(action)更可靠避免前端篡改参数。3.2 业务逻辑层EmployeeService里的事务边界与空值防御src/com/service/EmployeeService.java是真正的业务中枢。注意两个关键设计public class EmployeeService { private EmployeeDAO employeeDAO new EmployeeDAO(); // 方法1带事务控制的批量删除演示JDBC事务 public boolean deleteEmployees(ListInteger ids) { Connection conn null; try { conn JDBCUtil.getConnection(); // 从JDBCUtil获取连接 conn.setAutoCommit(false); // 关闭自动提交 for (Integer id : ids) { employeeDAO.delete(conn, id); // DAO层接收Connection复用同一事务 } conn.commit(); return true; } catch (SQLException e) { try { if (conn ! null) conn.rollback(); // 出错回滚 } catch (SQLException ex) {} return false; } finally { JDBCUtil.closeConnection(conn); // 必须关闭 } } // 方法2防NPE的员工新增实际项目必备 public boolean addEmployee(Employee emp) { if (emp null || StringUtils.isBlank(emp.getName())) { return false; // 拒绝空姓名 } // 设置默认值 if (emp.getGender() null) emp.setGender(男); if (emp.getSalary() null) emp.setSalary(new BigDecimal(5000.00)); return employeeDAO.insert(emp); } }为什么这里不用Spring声明式事务因为本包是纯Servlet架构没有Spring容器。JDBCUtil.getConnection()每次返回新连接所以必须手动setAutoCommit(false)并在DAO层透传Connection对象。若DAO方法不接收Connection事务将失效——这是新手最常翻车的点。3.3 数据访问层EmployeeDAO的SQL预编译与结果集映射src/com/dao/EmployeeDAO.java封装了所有JDBC操作。重点看listAll()方法public ListEmployee listAll() { ListEmployee employees new ArrayList(); String sql SELECT id, name, gender, department, salary, hire_date FROM employee ORDER BY id; try (Connection conn JDBCUtil.getConnection(); PreparedStatement ps conn.prepareStatement(sql); ResultSet rs ps.executeQuery()) { while (rs.next()) { Employee emp new Employee(); emp.setId(rs.getInt(id)); emp.setName(rs.getString(name)); emp.setGender(rs.getString(gender)); // 直接存字符串非枚举 emp.setDepartment(rs.getString(department)); emp.setSalary(rs.getBigDecimal(salary)); emp.setHireDate(rs.getDate(hire_date)); employees.add(emp); } } catch (SQLException e) { e.printStackTrace(); // 实际项目应记录log4j } return employees; }参数说明try-with-resources确保Connection、PreparedStatement、ResultSet自动关闭避免连接泄漏rs.getString(gender)返回数据库存储的原始字符串如男而非转换为Java枚举——简化设计降低耦合rs.getBigDecimal(salary)比rs.getDouble()更安全避免浮点精度丢失工资必须精确。4. 避坑指南5个让90%开发者卡住的致命细节4.1 现象访问http://localhost:8080/employee/list返回404原因Tomcat未正确部署ROOT.war或web.xml中servlet-mapping路径与URL不匹配。解决检查$TOMCAT_HOME/webapps/目录下是否存在解压后的ROOT/文件夹而非ROOT.war查看Tomcat启动日志搜索Deploying web application archive确认部署成功核对web.xml中url-pattern/employee/*/url-pattern与浏览器地址栏路径是否一致注意末尾斜杠若用IDE调试禁用IDE的自动部署改用Ant打包后手动复制ROOT.war。4.2 现象JSP页面中文显示为??或方块原因JSP文件本身编码、Tomcat响应头、MySQL连接URL三者UTF-8未统一。解决用Notepad或VS Code确认所有.jsp文件保存为UTF-8 without BOM在web.xml的CharacterEncodingFilter中确保param-valueUTF-8/param-value修改JDBCUtil.java中连接URLjdbc:mysql://localhost:3306/empdb?useUnicodetruecharacterEncodingUTF-8serverTimezoneGMT%2B8在JSP顶部添加% page contentTypetext/html;charsetUTF-8 %。4.3 现象新增员工后数据库无数据但页面跳转成功原因EmployeeDAO.insert()方法未调用conn.commit()或JDBCUtil.getConnection()返回了自动提交模式的连接。解决检查JDBCUtil.java中getConnection()方法确认conn.setAutoCommit(true)未被误设在EmployeeDAO.insert()末尾添加conn.commit()若DAO接收Connection参数更推荐方案在EmployeeService.addEmployee()中统一管理事务DAO只负责SQL执行。4.4 现象ant compile报错package javax.servlet does not exist原因WEB-INF/lib/中缺少servlet-api.jar或Ant未将Tomcat的servlet-api.jar加入classpath。解决从$TOMCAT_HOME/lib/servlet-api.jar复制到WebContent/WEB-INF/lib/修改build.xml在path idcompile.classpath中添加fileset dir${tomcat.home}/lib include nameservlet-api.jar/ /fileset重启Ant编译。4.5 现象登录后跳转到/employee/list却提示HTTP Status 404 – Not Found原因EmployeeServlet中response.sendRedirect(list.jsp)使用了相对路径而当前请求URL是/employee/login重定向后变为/employee/list.jsp但实际JSP在/employee/目录下。解决改为绝对路径重定向response.sendRedirect(request.getContextPath() /employee/list.jsp)或统一用RequestDispatcher转发request.getRequestDispatcher(list.jsp).forward(request, response)最佳实践所有页面跳转使用request.getContextPath()动态拼接避免硬编码。5. 进阶改造把“能跑”升级为“能用”的3个实战技巧5.1 把JSP页面转成Bootstrap响应式布局5分钟生效原生JSP多用HTML表格展示列表适配手机端效果差。无需重写逻辑只需替换employee/list.jsp的表格部分!-- 替换前原始table -- table trth姓名/thth部门/thth薪资/th/tr c:forEach items${employees} varemp trtd${emp.name}/tdtd${emp.department}/tdtd${emp.salary}/td/tr /c:forEach /table !-- 替换后Bootstrap卡片式布局 -- div classrow c:forEach items${employees} varemp div classcol-md-4 mb-4 div classcard h-100 div classcard-body h5 classcard-title${emp.name}/h5 p classcard-text strong部门/strong${emp.department}br strong薪资/strongspan classtext-success${emp.salary}元/span /p a href${pageContext.request.contextPath}/employee/edit?id${emp.id} classbtn btn-sm btn-primary编辑/a /div /div /div /c:forEach /div落地要点在WebContent/WEB-INF/web.xml中确认已引入Bootstrap CDN或下载CSS/JS到css/目录col-md-4表示中屏每行3列mb-4添加底部边距h-100使卡片高度一致${pageContext.request.contextPath}确保路径不依赖部署上下文即使不是ROOT.war也有效。5.2 为删除操作添加二次确认弹窗纯前端零Java改动employee/list.jsp中的删除链接a href${pageContext.request.contextPath}/employee/delete?id${emp.id} onclickreturn confirm(确定删除员工【${emp.name}】)删除/a为什么不用AJAX本包无jQuery依赖confirm()是浏览器原生API兼容IE8且删除后需刷新列表同步跳转更简单。若需异步可加一行script function deleteEmp(id) { if (!confirm(确定删除)) return; fetch(${pageContext.request.contextPath}/employee/delete?id id, {method: POST}) .then(r r.text()) .then(() location.reload()); } /script !-- 调用a href# onclickdeleteEmp(${emp.id})删除/a --5.3 日志增强用Log4j记录每次CRUD操作详情src/log4j.properties默认只输出ERROR级别。改为记录所有SQL执行# 设置根日志器 log4j.rootLoggerINFO, stdout, file # 控制台输出 log4j.appender.stdoutorg.apache.log4j.ConsoleAppender log4j.appender.stdout.layoutorg.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1} - %m%n # 文件输出每天滚动 log4j.appender.fileorg.apache.log4j.DailyRollingFileAppender log4j.appender.file.Filelogs/employee.log log4j.appender.file.layoutorg.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1} - %m%n # 关键开启Hibernate SQL日志即使不用HibernateJDBCUtil也可模拟 log4j.logger.org.hibernate.SQLDEBUG log4j.logger.com.dao.EmployeeDAODEBUG然后在EmployeeDAO.java的每个方法开头添加private static final Logger logger Logger.getLogger(EmployeeDAO.class); public ListEmployee listAll() { logger.debug(执行员工列表查询); // ...原有代码 }效果启动后logs/employee.log中会出现2023-10-05 14:22:33 [http-nio-8080-exec-1] DEBUG EmployeeDAO - 执行员工列表查询 2023-10-05 14:22:33 [http-nio-8080-exec-1] DEBUG EmployeeDAO - 查询SQL: SELECT id,name,gender,... FROM employee我带实习生时让他们先改这三处加Bootstrap、加confirm、加Log4j日志。一周后他们就能独立维护客户现场的类似系统——因为“能跑”只是起点“能用”才是交付标准。这些技巧不炫技但直击上线后最常被问的三个问题“页面能不能在手机上看”、“删错了能后悔吗”、“出问题时怎么查”希望帮到你。本文还有配套的精品资源点击获取