首页 / 资讯中心 / 文章详情

Java+SpringBoot+SSM构建HR管理系统:从数据库设计到权限控制的实战解析

Java+SpringBoot+SSM构建HR管理系统:从数据库设计到权限控制的实战解析 ★ FEATURED ARTICLE
HR管理系统是一类很典型的业务系统我这些年接过好几套类似的开发需求规模有大有小但核心逻辑惊人地一致员工档案、考勤、请假、薪资、部门管理再加上一套权限控制基本就是全部。这套基于 Java SpringBoot SSM 的人力资源管理系统就是围绕这些场景落地的一个完整方案附带源码、文档、调试步骤和讲解材料对于想从零学习 SSM 整合、准备毕业设计或者说想给中小团队快速搭一套人事管理工具的开发者来说都算得上是一份可以直接上手拆解的参考样本。系统本身不做花哨的东西就是把 HR 日常最头疼的那几件事——信息分散、流程靠人催、数据难统计——用一套 Web 应用串起来让管理员、HR、普通员工各用各的入口权限分明流程留痕。这篇文章我不打算只讲“项目有什么”而是把开发这套系统时最值得琢磨的模块设计、技术选型逻辑、数据库建模细节、核心代码实现和踩坑过程全部拆开讲清楚你可以照着思路自己复现一版也可以拿着这些细节去应对答辩或评审的追问。1. 项目拆解一套 HR 系统到底该装下什么1.1 HR 日常的痛点就是系统设计的出发点我在实际接触这类需求时发现一个很有意思的现象绝大多数中小公司并不是不想用专业人事软件而是觉得那些商业系统的功能太重、价格也不友好最后又回到 Excel 加纸质审批的老路上。结果就是员工花名册散落在好几个人的电脑里请假条在领导办公桌上躺了三天没人批月底统计考勤和薪资纯靠人工对着记录一条条核算效率低不说还容易出岔子。这套系统解决的核心问题其实就是信息统一管理和流程线上化。从使用者的视角来看系统里至少要出现三类角色。老板和 HR 希望能看到全局数据比如各部门人数、当月请假情况、薪资发放记录普通员工希望能够提交请假申请、查看自己的考勤和工资条系统管理员则关心账号、权限、菜单和基础数据维护。三类角色的诉求叠加在一起就决定了功能模块的边界系统必须同时满足“管人”、“管事”和“控权限”三个层面的需要。1.2 六大功能模块的职责切分很多人一上来就想把系统做得很庞大招聘、培训、绩效、社保全塞进去结果每个模块都做得浅尝辄止反而把核心功能拖垮了。这套系统的模块划分是经过取舍的只保留了 HR 管理中最刚性、最高频的六个部分模块核心功能使用角色组织管理部门增删改查、部门树展示、负责人设置管理员、HR员工管理员工档案录入与维护、照片上传、入职离职状态管理管理员、HR考勤管理上下班打卡记录、考勤状态异常处理、月度汇总员工、HR请假管理请假申请提交、审批流转、申请记录查询全员薪资管理基本工资与变动项设置、月度薪资核算、发放记录HR、管理员系统管理用户、角色、菜单权限、操作日志管理员这里有一个模块划分时的关键设计原则以员工信息为核心主数据其余模块都围绕员工进行数据关联。考勤要放到某个员工名下请假要和某个员工绑定薪资更离不开员工信息和部门归属。把这条主线理清楚后面设计数据库时就不会东一榔头西一棒槌。部门管理看起来简单但设计时要注意层级关系的表达。比如一个公司有研发部研发部下又分后端组、前端组这种父子关系在系统里需要通过部门表的父级字段来体现界面上则用树形结构展示。同时部门删除一定要做限制如果部门下还有在职员工应该拦截删除操作否则员工档案就会变成无归属的“孤儿数据”这在人事管理中是绝对要避免的。1.3 角色权限的三层划分权限设计是 HR 系统绕不开的环节因为薪资、员工联系方式这类数据非常敏感不可能让普通员工随意查看全部同事的信息。这套系统的权限模型采用了最常见的 RBAC 设计也就是“用户-角色-权限”三层结构。比如创建三个角色系统管理员、HR专员、普通员工。管理员能进系统管理模块HR能操作员工和薪资数据普通员工只能看到自己的档案、考勤和请假记录以及提交申请。在实际实现时权限控制要拆分成两个层面一是功能权限也就是某个角色能访问哪些菜单和按钮这是通过数据库权限表和后端拦截器共同实现的二是数据权限也就是同一个角色下不同的人能看到哪些数据范围像部门HR只能看本部门的员工这一层在毕设或中小型项目中往往做简化处理主要是靠查询条件里拼上部门ID来完成。这个取舍是合理的完整的数据权限体系实现成本很高对于几百人规模的使用场景来说功能权限加上部门过滤已经完全够用。2. 技术架构为什么偏偏是 Java SpringBoot SSM2.1 SSM 三件套各自管哪一层SSM 指的是 Spring、Spring MVC、MyBatis 这三个框架的组合它们的分工可以类比成一个小型公司的三个部门Spring 是总经理办公室负责统筹管理所有对象的创建和依赖关系也就是所谓的 IoC 容器和依赖注入Spring MVC 是前台接待所有请求都由它接收然后根据 URL 分发给对应的业务部门处理MyBatis 是档案室专门负责和数据库打交道把 SQL 写在 mapper 文件里执行完再把结果映射成 Java 对象。这三者配合起来的关系链是前端页面发起HTTP请求Spring MVC 的 Controller 接收请求调用 Service 层的业务方法Service 内部通过 MyBatis 的 Mapper 接口访问数据库数据返回后再逐层回传最终由 Spring MVC 渲染页面或返回 JSON 数据。整个过程清晰直接特别适合中小型业务系统。这也是为什么这套系统没有引入更复杂的技术框架因为在这个量级的业务逻辑下SSM 的复杂度刚刚好出问题也容易排查。2.2 那 SpringBoot 又扮演了什么角色用传统方式搭建 SSM 项目是件挺折磨人的事要写一堆 XML 配置、配数据源、配事务管理器、配视图解析器稍不留神版本就对不上。SpringBoot 的出现把这套繁琐的配置大幅简化了它采用的是“约定优于配置”的思路把常用的默认配置全部内置好你只需要在 application.yml 里写上数据库连接信息、端口号、文件上传大小等少数字段就能启动项目。更关键的是SpringBoot 内嵌了 Tomcat 容器以前要单独安装 Tomcat 再把 war 包扔进去部署现在一个命令 java -jar 就能直接跑起来这对于开发调试和后期交付都方便太多。这里有个容易让人产生误解的概念要讲清楚SpringBoot 并没有替代 SSM 中的任何一个组件它的底层依然使用 Spring 容器来管理 Bean依然支持 Spring MVC 来处理请求依然可以和 MyBatis 无缝整合。所以更准确的说法是这个项目是用 SpringBoot 作为底座把 SSM 整合得更加方便易用。2.3 单体架构还是微服务别陷入过度设计我在指导别人做这类系统时经常有人问“要不要做成微服务”。我的建议非常明确不要。微服务是为了解决大规模团队的独立部署、独立扩缩容、多技术栈混合等复杂问题而 HR 管理系统这类业务即便是大型企业成熟产品也完全可以用单体架构支撑更不用说这套面向中小规模场景的系统了。做成单体架构代码结构简单调试方便部署就是一个 jar 包一台普通服务器就能跑得稳稳的运维成本极低。答辩时如果被问到架构选型这个理由是非常站得住的。技术上选用单体架构还有一个好处就是数据一致性更容易保证。比如薪资核算这个流程涉及到员工基本工资、考勤扣款、请假天数等多个表的数据在单体应用里可以直接用本地事务把整个操作包起来任何一个环节出错都能整体回滚不会出现跨服务分布式事务那种让人头疼的补偿问题。架构是为业务服务的几万字代码的项目上微服务属于给自己找麻烦。2.4 权限方案与统一返回结构的设计取舍在登录认证方面常见的有两种方案传统 Session 会话和 JWT 令牌。这套系统采用的是 Session 加拦截器的组合登录成功后把用户 ID 和角色信息放入 Session然后注册一个全局拦截器拦截所有需要登录的请求从 Session 里校验用户是否存在。这个方案实现简单、状态管理方便服务端随时可以踢人下线非常适合非前后端分离或者后端渲染为主的项目。如果你的版本是前后端完全分离用 VUE 或 React 单独部署那建议改用 JWT 方案请求头里带 token后端通过拦截器解析 token 并校验有效期。不管哪种方案响应给前端的数据格式一定要统一。我习惯在项目里定义一个 Result 类包含 code、message、data 三个字段所有接口都返回这个结构成功时 code 为 200失败时根据业务场景返回不同的错误码。同时再配一个全局异常处理器用 RestControllerAdvice 捕获项目中的运行时异常和业务异常统一转成 Result 格式返回。这样一来前端处理数据时完全不用关心各种异常情况逻辑清爽不少这也是区分一个项目是不是“野路子”的细节标准之一。3. 数据库设计九张表如何撑起整个系统3.1 核心数据表的职责与关系数据库设计是这类管理系统最重要的环节表结构一旦定下来后续所有代码都在为它服务。这套系统的数据库我梳理为九张核心表每一张都有明确的职责边界用户表存登录账号信息角色表定义角色类型菜单权限表维护系统功能点部门表维护组织架构员工表存员工基本信息考勤表和请假表记录员工日常行为薪资表按月存储发放记录中间表 user_role 和 role_menu 分别建立用户与角色、角色与权限的多对多关系。表之间的核心关系链是用户表通过 user_role 关联角色用户通过员工ID关联到员工表员工表通过部门ID关联到部门表考勤、请假、薪资三张表又分别通过员工ID关联回员工表。这是一张典型的以员工为核心主数据的星型模型查询时从员工表出发可以很方便地关联到任意业务子表。设计时要把用户账号和员工档案分开原因很简单一个员工可能换账号一个账号也可能在员工离职后需要停用两者逻辑上独立才能分别管理。3.2 关键建表细节与 SQL 实现选段员工表可以说是整个系统信息量最大的表字段设计直接决定了后续功能的复杂度。核心字段我给出这段建表 SQL 做个参考CREATE TABLE employee ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT 主键ID, emp_no VARCHAR(20) NOT NULL UNIQUE COMMENT 员工编号, name VARCHAR(50) NOT NULL COMMENT 姓名, gender TINYINT DEFAULT 0 COMMENT 性别 0-未知 1-男 2-女, dept_id BIGINT NOT NULL COMMENT 所属部门ID, position VARCHAR(50) COMMENT 职位, phone VARCHAR(20) COMMENT 联系电话, email VARCHAR(100) COMMENT 邮箱, hire_date DATE COMMENT 入职日期, status TINYINT DEFAULT 1 COMMENT 状态 1-在职 0-离职, create_time DATETIME DEFAULT CURRENT_TIMESTAMP, update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_dept_id (dept_id), INDEX idx_status (status) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COMMENT员工表;这里有几个设计上的小心思值得说明。员工编号 emp_no 设置唯一约束它相当于员工在公司里的“身份证号”在薪资、考勤等所有业务操作中都用它做逻辑关联比用自增主键更稳定dept_id 和 status 分别建立索引因为这两个字段会频繁出现在查询条件里加索引能明显提升分页查询效率status 字段用的是 TINYINT 而不是直接删除记录这属于软删除策略员工离职后档案依然保留只是状态变为离职这对于后续追溯历史工资和考勤记录非常重要。请假表的设计则要重点考虑流程状态字段。我一般用 status 表示审批状态用数字 0、1、2 分别代表待审批、已批准、已驳回再用 approver_id、approve_time、approve_comment 三个字段记录审批人和审批意见。这组字段是流程留痕的最低配置没有它们审批记录就只是几个数字完全说不清楚“谁在什么时候批的”。工资表的表结构里除了基础工资 base_salary还要留出 bonus 和 deduction 两个字段用来表示绩效奖金和五险一金扣款等变动项后端按月计算最终实发金额 amount这样可以保证即便基础工资有调整历史月份的工资记录也不受影响。3.3 数据库设计的几个避坑清单第一点密码绝不能明文存储。很多学习项目为了图省事直接存明文密码这在真实系统里是绝对不允许的。推荐的做法是用 BCrypt 加密算法它每次生成的哈希串都带有随机盐值就算两个用户设置了完全相同的密码存储结果也不一样攻击者无法通过彩虹表反推。代码实现时不需要引入整个 Spring Security 框架单独引入 spring-security-crypto 依赖就足够。第二点不要过度迷信数据库物理外键。用 FOREIGN KEY 约束虽然能保证数据一致性但在高并发插入操作下会影响性能而且删除时容易报约束错误。这套系统采用的是逻辑外键也就是只在业务层面保证关联关系数据库层面通过索引来加速查询。这样做的好处是代码对数据的管理更灵活例如员工离职时可以先改状态再异步清理数据而不会被外键卡死。第三点日期时间字段处理要提前定好规范。MySQL 8.0 以上的时区问题很麻烦连接参数里一定要加上 serverTimezoneAsia/Shanghai否则会出现时间相差8小时的诡异问题。所有表统一使用 DATETIME 类型存具体时间日期字段像入职日期、请假日期用 DATE 类型避免把日期和时间混在一起增加查询难度。4. 实战环节从零搭一个 HR 系统的关键代码4.1 环境准备与工程骨架搭建开发这套系统我建议使用的环境组合是JDK 1.8、Maven 3.6 以上、MySQL 5.7 或 8.0、IDEA 开发工具。SpringBoot 版本建议选择 2.5.x这个版本和 JDK 8 的兼容性最好而且大量第三方依赖的适配信息都比较完善。切记不要贸然使用 SpringBoot 3.x因为 3.x 底层是 Spring Framework 6要求 JDK 17 起步如果你对版本迁移没有把握直接用 2.5.x 是最稳妥的选择。工程目录结构建议按下述分层来组织这是 SSM 项目最经典的分层方式src/main/java/com/example/hrms ├── controller # 控制层接收请求返回结果 ├── service # 业务层处理业务逻辑和事务 ├── mapper # 数据访问层MyBatis的Mapper接口 ├── entity # 实体类对应数据库表 ├── common # 公共模块统一返回结果、异常处理、工具类 ├── config # 配置类拦截器注册、文件上传等 └── HrmsApplication.java # SpringBoot启动类分层最重要的意义在于让依赖关系单向流动Controller 依赖 ServiceService 依赖 Mapper不能反过来。有的初学者图省事在 Controller 里直接调用 Mapper 的方法虽然短时间内项目能跑通但后期如果要改业务逻辑会发现到处都在改非常痛苦。坚持分层开发职责边界清晰也方便写单元测试。4.2 登录认证与拦截器的实现登录接口的逻辑不复杂核心是两步第一步用用户名查出用户记录比对密码是否正确第二步如果匹配成功将用户ID、用户名、角色信息存入 Session。密码比对我使用的是 BCryptPasswordEncoder 的 matches 方法因为数据库里存的是 BCrypt 加密后的密文不能直接和明文等号比较。拦截器是权限控制的执行者我写了一个 LoginInterceptor 类核心逻辑如下public class LoginInterceptor implements HandlerInterceptor { Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { // 放行预检请求 if (OPTIONS.equalsIgnoreCase(request.getMethod())) { return true; } // 从Session中获取用户信息判断是否登录 Object user request.getSession().getAttribute(loginUser); if (user null) { response.setContentType(application/json;charsetUTF-8); response.getWriter().write(JSON.toJSONString(Result.error(401, 未登录或登录已过期))); return false; } // 角色权限校验通过handler方法上的注解判断 HandlerMethod handlerMethod (HandlerMethod) handler; RequiresPermission requiresPermission handlerMethod.getMethodAnnotation(RequiresPermission.class); if (requiresPermission ! null) { String required requiresPermission.value(); // 从Session中取出角色权限列表判断是否包含required if (!hasPermission(request, required)) { response.getWriter().write(JSON.toJSONString(Result.error(403, 无权限访问))); return false; } } return true; } }这段代码里有两个值得学习的点。第一通过自定义注解 RequiresPermission 标注在 Controller 方法上拦截器在运行时读取这个注解并校验当前用户的权限信息这种方式比每个方法里手动写权限判断要优雅得多第二返回结果统一使用 Result 对象转 JSON哪怕是认证失败前端拿到的数据结构也和正常响应完全一致方便统一处理。拦截器写完后还要在 WebMvcConfigurer 配置类里注册它。注意注册时要用 addInterceptors 方法并设置排除放行的路径比如登录接口 /login、静态资源 /static/**、验证码接口等。这个步骤很容易被忽略一旦忘记排除登录接口就会形成死循环登录接口也需要拦截器验证但用户还没登录。4.3 员工管理核心接口的实现细节员工管理页面是系统里使用频率最高的功能通常会做成分页列表带多个筛选条件。查询条件一般包括姓名关键字、部门、入职日期区间、员工状态。这里使用 PageHelper 分页插件来简化分页逻辑代码如下Service public class EmployeeServiceImpl implements EmployeeService { Override public PageResultEmployeeVO pageQuery(EmployeeQuery query) { PageHelper.startPage(query.getPageNum(), query.getPageSize()); ListEmployeeVO list employeeMapper.selectByCondition(query); PageInfoEmployeeVO pageInfo new PageInfo(list); return PageResult.of(pageInfo.getTotal(), pageInfo.getList()); } }PageHelper 的工作原理是拦截 MyBatis 执行的 SQL自动拼接 LIMIT 语句用起来非常方便。但有一个坑必须注意PageHelper.startPage 之后紧跟的那一条查询语句才会被分页拦截如果中间插了其他查询操作分页就会错乱所以 startPage 必须和下一条 Mapper 查询紧挨在一起写中间不要插入任何代码。新增员工接口需要注意的是编号唯一性校验。员工编号是业务主键提交时先按 emp_no 查一次库如果已存在就直接抛出业务异常。保存时还需要处理照片上传我建议将上传的图片保存在服务器本地路径或对象存储中数据库只存文件访问路径的字符串字段不要用 BLOB 字段直接存二进制否则数据库会变得异常臃肿查询性能也会下降。4.4 请假审批流程的状态流转实现请假审批是这套系统里最接近“工作流”的功能但完全没有必要引入 Activiti、Flowable 这类重量级工作流引擎。对于请假这种典型的单级或两级审批场景用状态字段加权限控制就能完美实现代码简洁且逻辑清楚。请假流程的状态流转用下面的代码段来表示public void approve(Long leaveId, Integer approveResult, String comment, Long approverId) { LeaveRequest leave leaveMapper.selectById(leaveId); if (leave null) { throw new BusinessException(请假记录不存在); } // 校验当前状态必须是待审批 if (leave.getStatus() ! 0) { throw new BusinessException(该申请已被处理请勿重复操作); } // 审批结果1-通过 2-驳回 int newStatus (approveResult 1) ? 1 : 2; leave.setStatus(newStatus); leave.setApproverId(approverId); leave.setApproveTime(new Date()); leave.setApproveComment(comment); leaveMapper.updateById(leave); }这段简单代码背后藏着一个很重要的设计思想用状态机思维管理流程。状态只能按预定路径流转比如从待审批到已批准或已驳回不能从已批准再变回待审批。校验“当前状态必须是待审批”这一步就是状态机的落地保护。如果申请被驳回后允许员工修改再重新提交那过程就是把状态从已驳回重置为待审批同时清空审批意见。这样虽然代码简单但每一步都清晰可查。薪资模块的权限控制要单独特别注意。工资数据的查看和导出接口我建议在 Controller 方法上同时标注这个权限注解并且限制只有 HR 角色或管理员角色才能访问。工资计算时请假的已批准天数要从固定工资里按对应比例扣除这个规则如果太复杂不要全堆在 SQL 里写而是由 Service 层从数据库取出基础数据后在内存里计算更容易保证逻辑正确和单元测试覆盖。5. 常见问题与排查技巧实录5.1 高频问题速查表这部分我整理了开发调试这套系统过程中最常遇到的几个问题按现象、原因和解决方案整理成表方便你快速定位。问题现象根本原因解决方案项目启动端口被占用本地8080端口被其他进程占用修改 application.yml 中的 server.port或停掉占用进程连接数据库报 Access denied数据库账号密码不对核对 application.yml 中用户名密码MySQL8以上需要确认加密规则中文乱码数据库连接串没指定字符集在 JDBC URL 上加 characterEncodingutf8 和 useUnicodetrue接口 404 找不到Controller 没有包扫描到确认 Controller 类位置在启动类子包下或启动类加 MapperScanMyBatis 报 BindingExceptionMapper 接口和 XML 文件不一致检查 namespace 是否等于接口全路径、方法ID是否匹配登录后接口仍被拦截拦截器误拦截了已放行路径检查排除放行配置确认登录接口已添加 excludePathPatterns前端传参时间返回格式错误时间字段没配置格式化在实体类时间字段加 JsonFormat 注解指定 pattern文件上传失败上传大小超过默认限制在配置类里设置 spring.servlet.multipart.max-file-size5.2 三个值得记住的排查故事第一个故事发生在 MySQL 8.0 环境。项目在本地 5.7 跑得好好的放到另一台装了 MySQL 8.0 的机器上就报连接超时反复检查密码和端口都没问题。后来发现 8.0 版本对时区配置变得严格JDBC 连接串必须显式指定 serverTimezone否则驱动无法确定会话时区。当时加上 serverTimezoneAsia/Shanghai 后一切恢复正常。这个问题在 MySQL 5.7 上不会出现因此容易忽略。第二个故事更隐蔽页面样式全部丢失CSS 文件加载不出来。我第一反应是静态资源路径写错了检查了半天发现都没问题最后才意识到是拦截器把所有请求都拦住了配置的时候图省事用了一个/**通配符把/static/**路径也拦在了外面。从那以后我再写拦截器配置都会在注册时仔细区分路径匹配规则静态资源和登录接口必须加进排除列表。第三个故事是典型的依赖版本冲突。项目里同时引了 Old JSON 库和 Jackson 库Controller 返回对象序列化时两种库的注解混用导致实体类中部分字段无法序列化前端收到的 JSON 缺失字段。排查时用 postman 打接口直接看响应发现正常接口数据完整只有特定接口缺字段逐步对比后才锁定是注解优先级冲突。解决办法是删除多余依赖统一使用 SpringBoot 默认的 Jackson 作为 JSON 处理工具。这个经验告诉我写依赖时一定要克制能用 SpringBoot 原生能力解决的问题就不要额外引库。5.3 调试文档的价值与写法和演示流程调试文档在这个项目里扮演的角色不是简单的“安装步骤”而是一份可以从零到一复现系统的操作指南。我在整理这套项目的调试文档时会严格按这个顺序写环境版本确认清单、配置文件每项参数的说明、初始化数据库脚本执行方法、启动步骤及验证入口、核心功能测试用例。里面一定要包含每个接口的测试数据例如登录用哪个账号密码、新增员工填什么参数、薪资计算的期望结果是多少这些内容能极大降低使用者上手时摸不着头脑的概率。讲解视频的录制也很有讲究不能照着代码逐行念。我的建议是按照业务场景来演示先演示管理员登录创建部门和角色再演示 HR 添加员工并导入考勤然后切换到员工账号提交请假申请最后回到管理员账号审批并计算工资。让观看者跟着一条完整的业务线走下来比单纯罗列功能点要有效得多。6. 文档组织与答辩追问准备6.1 技术文档怎么组织才有价值如果这套系统是用于毕设或者项目评审技术文档的结构建议按章节推进写的时候立足“从问题到方案”的思路。摘要部分要直接用两三句话点明系统解决的核心问题和采用的关键技术需求分析章节按功能模块逐一说明业务流程系统设计章节放架构图和模块划分数据库设计章节先画 ER 图再用表格列出字段说明实现与测试章节放关键代码片段和测试截图。写文档时不要复制粘贴大段代码重点是解释“为什么这么实现”评审老师更关心你的设计思路。这个项目交付包里的 LW 部分即说明文档建议和调试文档分开。调试文档面向的是“如何跑起来”语言要口语化、步骤要傻瓜化正式说明文档面向的是“系统怎么做出来的”语言要规范、推理要闭环。两种文档定位不同混在一起会让两者都显得不够专业。6.2 答辩评审现场的追问应对答辩时评委会集中提问技术选型和业务细节这里挑几个高频问题分享一下应对思路。为什么选 SSM 而不是 Spring Boot 全家桶答案要点是SSM 是经典组合理解 Spring 核心原理和 MyBatis 运行机制更直接很多老业务系统也是这个架构掌握它有利于后续维护和迁移。而站在项目本身实际使用 SpringBoot 作为整合底座时则强调它简化了配置和部署。权限是怎么实现的把 RBAC 的三层关系讲清楚再结合拦截器代码说明认证和鉴权流程基本就能稳住。密码如何保证安全mention BCrypt 加密和随机盐机制就够了要是时间允许可以再顺带讲一讲为什么不能使用 MD5 加盐这种容易被暴力破解的方案。数据库为什么不用外键回答思路是逻辑外键更适合高并发和灵活的业务操作通过应用层保证一致性数据库索引提供查询性能。如果评审追问数据一致性怎么保证就把 Service 层事务管理搬出来说。如果被问到项目亮点我不建议说“界面好看”或者“功能齐全”最好说设计层面的亮点比如统一返回结构加全局异常处理、状态机控制审批流程、软删除保证单据可追溯这些细节会让人觉得你具备实际工程经验。最后说点个人体会接这类 HR 系统时最容易犯的错误是一开始就想着把功能做全结果项目进入中后期后核心流程反而没打磨好。我的经验是先把员工管理、部门管理、登录权限这三条最核心的链路跑通形成能用的最小闭环然后再逐步补考勤、请假、薪资这些外围模块。开发过程中配套保持调试文档的实时更新哪怕只是记录一个环境安装踩坑的小细节对后续交付也会有大帮助。系统做完之后可以想想还有哪些能自然扩展的地方比如数据导出、日志审计、消息提醒这些都是低成本高感知的加分项但前提依然是先把基础模块做稳了再说。
阅读完成 · 觉得有帮助?
咨询建站