十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

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

SSM框架实战:员工管理系统从数据库到部署完整实现

SSM框架实战:员工管理系统从数据库到部署完整实现 简介这是一套基于SSMSpring SpringMVC MyBatis框架与Java语言开发的企业级员工管理系统源码面向Java初学者、Web开发入门者及中小型团队技术实践者用于掌握企业级CRUD应用的完整开发流程与分层架构设计。资源共37个文件包含14个Java业务与控制类源码实现员工信息增删改查等核心逻辑、13个XML配置文件支撑Spring容器、MyBatis映射与MVC路由、4个JSP页面构成简洁可用的前端交互界面、2个properties配置文件管理数据库连接等运行参数以及gitignore、LICENSE等工程规范文件压缩包仅63KB轻量易读。已有335人学习下载适合作为SSM整合实战范例——代码结构清晰、模块职责分明涵盖DAO/Service/Controller三层划分与前后端基础交互可直接导入IDE运行调试是理解Java Web企业开发标准流程的优质入门素材。 直接说一个很多人没注意过的事实SSM 这套组合Spring SpringMVC MyBatis在 JavaWeb 项目里被念叨了很多年现在的新项目确实多数已经转向 Spring Boot但企业里仍有大量老系统跑在 SSM 上。你要是去翻招聘网站Java 后端岗位描述里“熟悉 SSM 框架”这句话依然挂在不少 JD 上。换句话说用 SSM 做一个员工管理系统这件事本身既是练习也是摸底——把这套源码跑通、改明白你就能理解 Spring 的 IoC/DI、SpringMVC 的请求流转、MyBatis 的持久层映射这三个核心技能为后面学 Spring Boot 打下底子。这篇内容我会把整个员工管理系统的需求拆解、数据库设计、后端实现、前端对接、环境部署和调试思路从头到尾捋一遍。不夸功能只说实际怎么落地。你拿到这套源码不是只看它能不能跑而是要知道每个文件为什么存在、每个配置为什么这么写、遇到报错怎么定位。1. 系统需求分析与功能定位1.1 为什么选择员工管理系统作为 SSM 练习项目很多新手学完 SSM 三大框架的独立教程后最大的困惑是“这三个东西怎么串起来”。单独看 Spring就是一个 Bean 工厂单独看 MyBatis就是 SQL 映射单独看 SpringMVC就是请求路由。但真实项目里用户发起一个 HTTP 请求经过 Controller、Service、Mapper再回到前端页面整个过程是连贯的。员工管理系统刚好覆盖了完整的 CRUD、分页、模糊搜索、登录校验、级联关系这些高频场景没有复杂的业务规则干扰适合把框架知识拼成一条完整的链路。我见过不少学习项目要么是纯增删改查的 Demo要么是抄的商城项目业务复杂到根本顾不上看框架本身。员工管理系统的好处在“业务简单但结构完整”员工属于部门每个员工有岗位、薪资、入职时间管理端需要做登录拦截和权限区分。这些需求刚好可以用来演示一对一关联查询、事务管理、Session 拦截器这些 SSM 的经典用法。1.2 功能模块拆解与用例分析按照常见的员工管理系统需求我把功能拆成四大块系统登录、员工管理、部门管理、系统辅助功能。系统登录模块包含用户认证和权限拦截。用户登录后把用户信息放入 Session后端用一个拦截器统一校验未登录请求直接重定向到登录页。这里顺便可以做角色区分比如管理员和普通员工普通员工只能查看和修改自己的信息管理员能做全量维护。员工管理模块是系统核心包含员工信息的列表展示、条件搜索按姓名、部门、入职时间范围、新增、编辑、删除以及员工详情查看。删除这里要特别留意真实系统不会物理删除员工数据通常用状态字段做逻辑删除也就是把 is_deleted 从 0 改成 1查询时默认过滤掉已删除数据。这种设计一开始就要有否则后面数据恢复就只能靠数据库备份碰运气。部门管理模块相对简单就是部门信息的增删改查。但要注意部门表与员工表存在主外键关系删除部门前必须检查该部门下是否还有在职员工。如果直接删要么数据库报外键约束错误要么业务上出现无部门的员工记录。所以我自己的实现方案是删除部门时先统计该部门下的员工数大于 0 就提示“请先调整该部门的员工”。辅助功能包括操作日志记录和修改密码。日志这块我用的是 Spring 的 AOP 思想做简化版在 Service 层记录操作行为包括操作人、操作时间、操作内容。不需要引入完整 AOP 注解框架只做基础实现目的是让刚接触的人理解“方法拦截”这件事在业务里是怎么用的。1.3 技术选型取舍SSM 还是 Spring Boot你可能要问为什么不直接学 Spring BootSpring Boot 确实是现在的主流但直接学 Boot 的问题是它把很多配置细节都自动处理掉了你很难理解底层发生了什么。SSM 的配置每一步都显式存在Spring 容器怎么加载、MyBatis 怎么扫描 Mapper、SpringMVC 怎么映射请求这些在 XML 里一目了然。从学习路径上讲SSM 是“用配置理解原理”Spring Boot 是“用约定简化开发”。两者不是替代关系而是递进关系。我在实际开发中见过不少只懂 Spring Boot 的开发者遇到配置失效、自动装配冲突时就无从下手就是因为缺乏对底层 Bean 管理机制的理解。做这个员工管理系统就是补这一课。如果你的目标是快速出活可以直接用 Boot但如果想理解框架本身SSM 仍然是很好的教材。这套源码里我用的是经典 XML 注解混合配置既保留配置的可见性又减少重复代码。2. 数据库设计与表关系设计2.1 数据表清单与字段规划数据库设计是这类系统的地基表结构不合理后面写代码的时候会到处别扭。我先列一下表设计再逐个解释字段取舍的依据。employee员工表id主键自增emp_no员工编号唯一索引name姓名gender性别birthday出生日期id_card身份证号phone手机号email邮箱address住址dept_id所属部门 ID外键position职位salary薪资entry_date入职日期status状态1 在职0 离职is_deleted逻辑删除标记create_time、update_time创建和更新时间department部门表id、dept_name、description、create_time、update_timeuser系统用户表id、username、password加密存储、real_name、role角色、status这三张表基本覆盖了系统的所有业务实体。没有把员工表和用户表合并是因为员工是组织架构里的受管对象登录账号是操作系统的身份凭证两者职责不同。举个例子公司里实习生也属于员工但可能没有系统登录权限相反系统管理员账号不一定对应该员工档案。2.2 建表 SQL 与初始化数据我用的数据库是 MySQL 5.7字符集选 utf8mb4。这里必须强调一下不要用 utf8因为 utf8 在 MySQL 里最多存 3 字节遇到 emoji 或者生僻字会直接报错。utf8mb4 才是完整的 UTF-8。初始化数据时我预置了一个管理员账号和一个测试部门方便第一次运行就能立刻登录体验。密码不能明文存我用的加密方式是 MD5虽然现在暴力破解风险高但在教学项目里够用而且比明文好太多。生产环境建议升级为 BCrypt这也是我在代码注释里特别标注的一个点。2.3 关联查询与三层映射设计员工表的 dept_id 关联部门表的 id查询员工列表时需要同时显示所属部门名称。这个在 MyBatis 里的实现有两种方式一种是写一个 resultMap 做嵌套映射另一种是写一个包含部门名称的 VO 类用连接查询直接映射。我在源码里用的是第二种因为部门名称只是一个展示字段不需要嵌套对象直接用 join 查询一把梭更直观。但要注意一个细节MyBatis 里如果开启了驼峰命名映射mapUnderscoreToCamelCasetrue那么数据库字段 dept_name 可以自动映射到 Java 属性的 deptName。如果没有开启就需要在 resultMap 里手动指定 column 和 property 的对应关系。这个开关是一行配置的事但对开发效率影响很大我建议一律打开。3. 后端框架搭建与核心实现3.1 项目结构规范与分层思想一个标准的 SSM 项目不管用 Maven 还是手动导包我都建议严格按三层结构划分包名controller、service、mapper也叫 dao、entity也叫 pojo/bean。源码里我的包结构是这样com.company.ems.controller接收请求参数校验调用 Servicecom.company.ems.service业务逻辑处理事务边界在这里com.company.ems.mapperMyBatis 的接口定义com.company.ems.entity实体类与表字段对应com.company.ems.common公共类比如分页结果、统一返回结果、拦截器分层不只是规范问题更多是“变更的隔离”。比如数据库从 MySQL 换成 Oracle只需要改 Mapper 里的 SQL前端从 JSP 换成 Vue只需要改 Controller 层的数据返回加一个缓存逻辑只需要在 Service 层做处理。如果所有代码堆在一个 Servlet 里任何改动都要层层排查维护成本直线上升。3.2 Spring 与 MyBatis 整合的配置细节Spring 与 MyBatis 整合的关键是 SqlSessionFactory 的创建和 Mapper 的扫描注册。在 Spring 的配置文件中我做了三件事配置数据源、配置 SqlSessionFactoryBean、配置 MapperScannerConfigurer。数据源用的 Alibaba Druid因为 Druid 自带监控页面可以查看连接池状态和 SQL 执行情况对本地调试很有帮助。SqlSessionFactoryBean 里最关键的配置是 mapperLocations我设为 classpath:mapper/*.xml这样 XML 文件里的 SQL 语句就能与 Mapper 接口关联起来。很多人在这里出错XML 文件放错位置或者路径写错导致运行时报 invalid bound statement (not found)。这个报错在 SSM 项目里出现频率极高后面我会专门展开讲。事务管理上我配置了 DataSourceTransactionManager然后用 Transactional 注解标注在 Service 层方法上。这里补充一个原理层面的解释Spring 的事务是通过 AOP 动态代理实现的。外部调用 Service 方法时实际上是调用代理对象的方法代理对象先开启事务、执行方法、再根据方法是否抛出异常决定 commit 还是 rollback。注意同一个类内部方法之间的调用不会经过代理所以 Transactional 不生效。这是一个很容易踩的坑如果你写了一个方法它内部调用了同一个类里另一个带 Transactional 的方法事务是不会被管理的。3.3 SpringMVC 控制器设计与接口规范Controller 层的职责是参数接收和结果返回不写业务逻辑。员工列表的 Controller 我设计了两个入口一个返回页面一个返回 JSON 数据。返回页面的方式用的是传统的 ModelAndView 或者 Model 参数Controller 方法里从 Service 拿到数据后放进 Model然后返回视图名称SpringMVC 结合视图解析器渲染出 JSP 页面。返回 JSON 的方式我引入了 Jackson在方法上标注 ResponseBodySpringMVC 自动把返回对象序列化为 JSON配合前端 Ajax 使用。这两种方式我都写了目的是让你理解 SpringMVC 同时支持服务端渲染和前后端分离模式。现在流行的 Spring Boot 接口开发本质上就是第二种方式的自动配置简化版。接口设计上我习惯遵循 REST 风格但又不过度追求纯粹的 RESTful。比如获取员工列表是 GET /employee/list新增员工是 POST /employee/add更新员工是 POST /employee/update删除员工是 GET /employee/delete/{id}教学项目方便浏览器直接访问测试。如果是真实前后端分离项目删除应该用 DELETE 方法。这里的取舍是方便理解优先规范其次。3.4 MyBatis 动态 SQL 与分页实现员工列表的搜索条件是不确定的可能只按姓名搜也可能姓名和部门同时搜。如果针对每一种组合都写一条 SQL会非常冗余。MyBatis 的where和if标签就是解决这个问题的。一个动态 SQL 方法就能覆盖所有搜索条件组合。分页有两种实现自己写 LIMIT 语法或者用 PageHelper 插件。PageHelper 的原理是拦截器在执行查询前自动改写 SQL在语句末尾追加 limit 参数然后查询总记录数。我在这套源码里用的是手写 LIMIT因为手写能让你理解分页的本质后面接 MySQL 高版本批量数据优化时也更清楚。分页查询的核心是两条 SQL一条查询记录总数一条查询当前页数据。Controller 接收 pageNum 和 pageSize 参数Service 层计算 offset偏移量Mapper 传入 offset 和 size。PageHelper 虽然方便但使用不当会有内存溢出和线程安全问题新手很容易中招。3.5 登录拦截与 Session 管理登录功能的核心是 Session 状态管理。用户提交用户名密码后Service 层校验密码是否正确正确则把用户对象放入 Sessionkey 名为 loginUser。然后定义一个 HandlerInterceptor 作为登录拦截器重写 preHandle 方法在这里判断 Session 是否包含 loginUser。注意拦截器要配置放行路径登录接口、登录页面、静态资源CSS、JS、图片都必须放行不然页面加载时会因为样式文件被拦截而错误。我最初做的时候忘记放行静态资源整个页面没有任何样式排查了半天后来才发现拦截器把静态资源也拦了。角色权限控制我用一个简单的 filter 逻辑实现用户在 Session 中存有 role 字段如果访问管理员接口而 role 不是 admin则直接返回 403 页面。不引入 Shiro 或 Spring Security就是为了让逻辑足够透明适合理解“认证 授权”的基本流程。4. 前端页面开发与交互设计4.1 页面布局与列表展示前端我用的是 JSP JSTL Bootstrap 的组合。虽然这种组合技术比较老但有两个好处第一SSM 经典项目基本都是这个套路网上资料最多第二JSP 的服务端渲染方式可以直接使用 EL 表达式和后端数据交互减少手写 Ajax 的工作量。整体布局用了经典的左侧菜单 右侧内容区。左侧菜单包含员工管理、部门管理、修改密码、退出登录四个入口。右侧区域用 iframe 嵌入对应页面。这个布局在管理系统里非常经典即使是现在很多后台管理系统的前端框架依然能看到这种结构的影子。员工列表页是 Bootstrap 的表格组件表头固定数据行循环输出。表格操作列提供“编辑”和“删除”两个按钮。删除按钮弹出确认框确认后发起 Ajax 请求编辑按钮跳转到编辑页面并携带员工 ID后端根据 ID 查询回显数据。4.2 表单校验与 Ajax 交互新增和编辑员工共用一个表单页面通过是否携带 ID 判断是新增还是编辑。表单校验分两层前端用 HTML5 的 required 属性和简单 JavaScript 校验后端在 Controller 里也做一次参数校验。前后端都校验是规范不能只依赖其中一层。Ajax 交互用的是 jQuery 的 $.ajax 方法。删除员工的请求就是典型的 Ajax 应用场景像删除这种风险操作不会用普通超链接直接跳转而是先请求确认再异步发送请求成功后刷新页面数据。如果响应不成功也要用弹窗提示用户失败原因比如员工正被引用、数据库异常等。这类细节决定了系统“用起来是否专业”。薪资和日期这类字段的格式要特别注意数据库里日期是 Date 类型JSON 序列化时默认会变成时间戳格式前端显示出来就是一串数字。解决办法是在日期字段上配置 Jackson 的 JsonFormat 注解指定 pattern 为 yyyy-MM-dd。这个坑几乎每个做管理系统的人都会遇到第一次看到页面上显示 158500000000 这种数字的时候基本都是一脸懵。4.3 分页组件的实现思路分页组件是我的一个 WebUtil 工具类完成的。分页数据由 PageResult 对象封装包含总记录数、总页数、当前页、每页条数、当前页数据列表等字段。前端 JSP 页面根据这些字段渲染出“上一页、下一页、页码”按钮保留当前搜索条件。实现分页最容易被忽略的是搜索条件的回传。比如你搜索了“张三”后点第 2 页请求需要把 keyword 参数带上否则第 2 页会变成无条件的全部数据列表。所以我在生成分页链接时会动态拼接搜索条件参数。这个逻辑不复杂但遗漏会出现“翻页后搜索条件丢失”的问题。5. 开发环境准备与源码运行说明5.1 环境版本与工具清单我在源码的 README 里整理了完整的环境清单。这里再按实际测试情况强调一遍JDK 1.8、Maven 3.6.x、Tomcat 8.5、MySQL 5.7。你如果非要用 JDK 17不是不行但 Spring 5.x 版本与高版本 JDK 兼容性要看具体小版本建议直接按清单环境来减少不必要的麻烦。IDEA 版本不限但要注意 Maven 仓库路径和 JDK 配置。克隆项目后先用 Maven 命令 clean compile 看看依赖能否正常下载。如果长时间卡在下载进度把国内镜像配置加上。这里补充一点很多人依赖下不下来的问题其实是 IDEA 里 Maven 的 settings.xml 没配置对。你怎么确认自己在用哪个 settings.xml在 IDEA 的 Maven 设置界面直接看 User settings file 的路径确认自己配置的是这个文件。5.2 数据库初始化的完整步骤第一步创建数据库。我提供了 init.sql 脚本直接执行即可包含建库、建表、插入初始数据。如果你的 MySQL 里已有同名数据库记得先备份再执行。第二步修改数据库连接配置。连接信息集中在 jdbc.properties 文件里包括 url、username、password。URL 我写的是 jdbc:mysql://localhost:3306/employee_system?useSSLfalsecharacterEncodingutf8mb4这里要重点说明两个参数useSSLfalse 是在本地开发时避免 SSL 握手警告characterEncodingutf8mb4 是防止中文乱码的关键。很多人数据库服务端是 utf8mb4但连接串没指定编码结果插入中文变成问号这个坑建议从源头上避开。第三步发布到 Tomcat。在 IDEA 里配置本地 TomcatDeployment 选择 war explodedApplication context 建议设为 /ems。注意这个上下文路径会直接影响访问地址如果改成别的后面所有 URL 都要跟着变。5.3 项目启动后的验证路径启动 Tomcat 后访问 http://localhost:8080/ems/ 正常情况下会跳转到登录页面。用预置的管理员账号登录后应该进入管理系统主页左侧菜单可以正常切换。点击员工管理能看到初始化的员工测试数据新增一条记录重新打开列表新记录应该出现编辑记录页面能正确回显原有数据删除记录弹窗确认后刷新页面记录消失。如果任何一步不符合预期不用慌这类项目的报错基本都是配置文件问题不是代码本身的问题。下面我整理了一份高频问题速查表你可以对照排查。6. 调试实录与高频问题排查6.1 常见异常速查表我平时最喜欢做的事就是收集报错因为报错才是最真实的学习材料。下面这个表可以说是 SSM 项目最常见的异常集合每一条我都亲手踩过。报错信息可能原因解决方案Invalid bound statement (not found)Mapper 接口和 XML 的 namespace 不一致或 XML 未扫描到检查 namespace 全限定名、method id、mapper-locations 路径ClassNotFoundException: org.springframework.web.servlet.DispatcherServletSpringMVC 的 jar 未打包到 lib检查 IDEA Artifacts 的 Output Layout确认 jar 在 WEB-INF/lib中文乱码数据库连接串、页面编码、服务端编码不一致连接串加 characterEncodingutf8mb4页面设 UTF-8配置 CharacterEncodingFilter数据库连接超时MySQL 未启动或密码错误确认 MySQL 服务状态核对 jdbc.properties404 错误访问路径与 Controller RequestMapping 不一致或项目未正确部署检查控制台日志中 SpringMVC 映射的 URL核对浏览器地址没有 Spring 的 Bean 实例包扫描路径配置错误确认context:component-scan的 base-package 覆盖到 controller、service、mapper前端页面无样式拦截器拦截了静态资源在 interceptor 配置中加mvc:resources或排除路径实体类是 nullEntity 字段与表字段不一致开启驼峰映射或在 resultMap 中指定映射关系6.2 让我曾经通宵排查的配置问题我在本地新拉取这套源码测试时出现过一次比较诡异的问题登录页能正常打开但输入账号密码点击登录后页面卡住不动控制台没有报错浏览器 Network 里看到请求被挂起。后来发现是数据库连接池配置中 initialSize 和 maxActive 配置不合理加上 MySQL 连接长期不用被服务端关闭而连接池里的旧连接没被自动检测导致第一次真实查询时就卡死了。Druid 的配置里加上 testWhileIdletrue 和 validationQuerySELECT 1 之后问题解决。另外一个高频问题是 Spring 的配置文件加载顺序。web.xml 里有一个 contextConfigLocation 参数它指定 Spring 根容器的配置文件路径。如果这里写错了Spring 容器根本不会初始化。很多项目会用 classpath:spring/applicationContext.xml 这种带路径的写法你必须保证这个路径与实际文件位置一致。我遇到过有人把 XML 放在 src/main/java 目录下因为某些教程就是这么放的这也能运行但不推荐还是放 resources 里更规范。6.3 从源码运行到二次开发的建议当这套系统能正常跑起来以后不要急着换下一个项目。我建议你按下面的顺序做几个小改造每个都不难但能帮你把框架知识真正变成自己的第一把密码加密从 MD5 换成 BCrypt。这个改造会涉及注册/登录逻辑让你理解“密码加盐哈希”和普通哈希的本质区别。第二把分页从手写 SQL 换成 PageHelper 插件对比两种实现方式理解插件原理。第三把删除员工改成逻辑删除加深对“危险操作留有余地”这个设计观念的理解。第四把 JSP 页面返回改成 Vue3 接口返回格式模拟一次前后端分离升级。这四个改造做完你对 SSM 的理解会比单纯跑源码高出几个层次。前面我提到过 Vue3 连接 SSM 框架的需求本质上就是 Controller 层返回纯 JSON前端用 axios 或 fetch 去调用接口。改造过程中你会发现SpringMVC 作为一个 MVC 框架返回 JSON 和返回视图其实只是配置和注解上的差异理解了这一点后面学 Spring Boot 就顺理成章。说实话员工管理系统在功能上没有任何新颖之处但正因为它的功能足够常见才能把 SSM 框架的每一个关键机制都展示出来。我个人在实际运行这套源码时最大的体会是出错最多的地方永远不是业务逻辑本身而是配置。遇到报错时先检查配置、再检查依赖、最后再看代码用这个顺序排查能省下大量时间。希望这篇内容能帮你在 SSM 的学习路上少踩几个坑。本文还有配套的精品资源点击获取
返回列表