news 2026/5/1 9:37:11

基于Java的工资管理系统毕业设计:从零实现到避坑指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
基于Java的工资管理系统毕业设计:从零实现到避坑指南


基于Java的工资管理系统毕业设计:从零实现到避坑指南


1. 背景痛点:为什么“能跑”≠“能毕业”?

第一次做毕业设计,大多数同学都会把“能跑起来”当成终点。可真正到了答辩现场,老师一句“如果员工并发调薪,你的事务能保证一致性吗?”就让场面瞬间凝固。下面这几个坑,90% 的 Java 项目都会踩:

  • 紧耦合:所有 SQL 直接写在 JSP 里,Service 层纯当“传话筒”,后期换个数据库差点把键盘掀了。
  • SQL 注入:用 Statement 拼接字符串,演示时把or 1=1当工号输入,全表数据秒出,老师微笑不语。
  • 事务失效:Spring 声明式事务一个@Transactional就完事,结果方法被同类内部调用,回滚直接罢工。
  • 权限裸奔:把“是否为管理员”存 Cookie,前端改 0 为 1 直接进后台,演示当场社死。
  • 代码复制:每个模块都有一段“分页+模糊查询”的重复代码,导师问“你这叫 DRY?”只能尴尬陪笑。

痛定思痛,下面给出一条“新手也能复制”的逃生路线。


2. 技术选型:Spring Boot 为什么赢?

维度Servlet + JSPSpring Boot + MyBatis
依赖管理手动导 jar,版本冲突到怀疑人生起步依赖,Maven 一行搞定
配置量web.xml、spring.xml 双份暴击约定大于配置,yml 即可
监控自己写 filter 统计 QPSactuator 端点直接看
部署打 war 丢 tomcat,本地和线上环境不一致内嵌容器,jar 包一键java -jar

JPA vs MyBatis 怎么选?毕业设计场景里,复杂报表、灵活字段是常态。JPA 的自动 SQL 在“多表+动态条件”下常常翻车,而 MyBatis 写 SQL 直观,调优空间更大,对新手调试友好。一句话:能看懂 SQL,才能睡得踏实。



3. 模块化设计:先画饼再写码

3.1 工程结构(Clean Code 版)

salary-system ├─ common // 工具、常量、全局异常 ├─ employee // 员工档案 ├─ salary // 薪资计算核心 ├─ security // 登录、鉴权、密码加密 ├─ report // 报表导出 └─ admin // 系统管理(字典、参数)

每个模块都按controller → service → mapper → entity/dto/vo四层展开,同层只依赖下层,禁止横向调用,编译期就能发现循环依赖。

3.2 数据库 ER 简图

  • 员工表 t_employee(id, name, dept_id, base_salary ...)
  • 部门表 t_department
  • 用户表 t_user(登录用)
  • 角色表 t_role & 中间表 t_user_role
  • 工资表 t_salary(月份+员工联合唯一索引,保证幂等)

3.3 关键接口设计

  • 员工调薪:PUT/employee/{id}/salary传入“新基本工资”,记录旧值→写流水→更新主表,三步一个事务。
  • 工资计算:POST/salary/calculate?month=2024-05传入月份,批量异步计算,接口只返回任务编号,避免超时。
  • 权限注解:自定义@RequiresRoles("HR"),利用 Spring AOP 拦截,比写 if-else 清爽太多。

4. 核心代码:薪资计算 Service 片段

下面给出“月薪=基本工资+绩效-社保-个税”的最小可运行示例,已填注释,可直接粘贴进 IDE 跑单测。

@Service @Slf4j @RequiredArgsConstructor public class SalaryCalculationService { private final EmployeeMapper employeeMapper; private final SalaryItemMapper itemMapper; private final SalaryMapper salaryMapper; /** * 计算指定月份工资,保证幂等:若已存在则跳过 */ @Transactional(rollbackFor = Exception.class) public void calculateMonthSalary(String month) { // 1. 查询所有在职员工 List<Employee> employees = employeeMapper.selectActive(); for (Employee e : employees) { // 2. 幂等校验 if (salaryMapper.exists(e.getId(), month)) { log.warn("salary already exists, skip empId={}", e.getId()); continue; } // 3. 组装各项 BigDecimal base = e.getBaseSalary(); BigDecimal perf = itemMapper.sumPerformance(e.getId(), month); BigDecimal social = SocialUtil.calc(base); // 社保固定比例 BigDecimal tax = TaxUtil.calc(base.add(perf).subtract(social)); // 累计预扣 BigDecimal finalAmount = base.add(perf).subtract(social).subtract(tax); // 4. 落库 Salary s = Salary.builder() .empId(e.getId()) .month(month) .baseSalary(base) .performance(perf) .social(social) .tax(tax) .finalSalary(finalAmount) .build(); salaryMapper.insertSelective(s); } } }

单元测试怎么写?用@SpringBootTest + @Transactional自动回滚,既能断言,又不污染库,毕业答辩现场演示屡试不爽。


5. 安全与性能:把“能跑”升级成“能扛”

5.1 密码加密

  • 明文存密码 = 0 分;MD5 哈希 = 50 分;BCrypt 加盐 = 100 分。
  • Spring Security 自带BCryptPasswordEncoder,encode 后长度 60 位,验证时无需自己盐值。

5.2 SQL 注入

  • MyBatis#{}占位符预编译,SQL 注入概率趋近于 0。
  • 动态排序字段不能用#{},用<choose>+白名单校验,防止 order by 后面被拼接。

5.3 并发与事务

  • 批量更新工资时,在 t_salary 建唯一索引(emp_id, month),利用数据库抛DuplicateKeyException实现幂等。
  • 事务方法一定要 public,同类自调用请用 AopContext 或拆到新 Bean,否则 Spring 无法代理。

5.4 简单压测

  • 本地笔记本 4C8G,连接池默认 10 线程,2000 员工 * 12 月历史回算,平均 RT 1.3s,CPU 峰值 60%,无 FullGC。
  • 把 Druid 连接池调到 maxActive=30,RT 降到 0.7s,足够毕设答辩“性能”章节交差。


6. 生产环境避坑指南

  1. 数据库连接池
    阿里云 MySQL 5.7 默认 max_connections=200,毕设演示时把连接池 maxActive 设 100,结果老师同时开 5 台手机热点刷新,直接把库打挂。调回 30 并加等待超时,世界瞬间安静。

  2. 事务回滚失效
    捕获异常后 log 一把,又 throw 出去,事务正常回滚;若 catch 后吞掉异常,Spring 以为你“已处理”,不回滚,数据当场裂开。

  3. 前端 Mock
    本地没网?用 Mock.js 拦截 Ajax,返回随机工资条,演示流畅不掉链。记得上线前把 mock 开关干掉,否则真发钱时发现数字全是假的,HR 要来砍人。

  4. 日志级别
    生产环境 root 级别 INFO 足够,把 SQL 日志调成 DEBUG 会刷屏,磁盘 1 天 3G,云盘报警比工资条先到。

  5. 端口与防火墙
    云服务器 3306 只对 Web 机开放,后台管理端口 8080 走 Nginx 反向代理,再配 HTTPS,答辩老师问“安全怎么做”时,直接把锁形图标甩给他看。


7. 留给你的思考题

单公司场景跑通后,只要再加一个company_id字段,所有表按租户隔离,登录时把公司编码塞进 JWT,就能升级成 SaaS 多租户。或者把“导出工资 Excel”功能排进日程:用阿里巴巴 EasyExcel,2 行代码把 2 万条数据流式写出,内存稳在 50M 以内,老师看了都说“像商业软件”。

毕业设计不是句号,而是把“写能跑的代码”练成“写能用的系统”。下一步,你会把多租户、分布式锁、微服务都安排上吗?评论区聊聊你的计划,我们下篇再见。


版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 7:10:05

告别设计障碍:这款插件如何让英文界面秒变中文?

告别设计障碍&#xff1a;这款插件如何让英文界面秒变中文&#xff1f; 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 你是否曾在深夜加班时&#xff0c;对着Figma满屏的英文菜单抓耳挠…

作者头像 李华
网站建设 2026/5/1 4:46:09

Magma多模态AI智能体5分钟快速上手:从零搭建你的第一个智能助手

Magma多模态AI智能体5分钟快速上手&#xff1a;从零搭建你的第一个智能助手 1. 为什么你需要一个5分钟就能跑起来的多模态智能体 你有没有遇到过这样的情况&#xff1a;想做个能看图说话的AI助手&#xff0c;结果光是环境配置就折腾半天&#xff1b;或者想试试让AI理解界面截…

作者头像 李华
网站建设 2026/5/1 6:16:09

OFA-VE效果展示:监控截图与值班日志‘发现异常人员’描述逻辑验证

OFA-VE效果展示&#xff1a;监控截图与值班日志‘发现异常人员’描述逻辑验证 1. 什么是OFA-VE&#xff1a;不是炫技&#xff0c;而是可落地的视觉逻辑验证工具 你有没有遇到过这样的场景&#xff1a; 值班人员在监控后台看到一张模糊的夜间抓拍图&#xff0c;旁边手写日志写…

作者头像 李华
网站建设 2026/5/1 6:13:54

MetaTube插件:跨媒体元数据整合的技术架构与实现方案

MetaTube插件&#xff1a;跨媒体元数据整合的技术架构与实现方案 【免费下载链接】jellyfin-plugin-metatube MetaTube Plugin for Jellyfin/Emby 项目地址: https://gitcode.com/gh_mirrors/je/jellyfin-plugin-metatube 一、技术价值定位 1.1 传统元数据管理方案的技…

作者头像 李华
网站建设 2026/5/1 7:12:53

保姆级教程:手把手教你部署阿里开源语音模型SenseVoiceSmall

保姆级教程&#xff1a;手把手教你部署阿里开源语音模型SenseVoiceSmall 你是否试过上传一段会议录音&#xff0c;却只能得到干巴巴的文字&#xff1f;是否希望AI不仅能听懂你说什么&#xff0c;还能感知你说话时是兴奋、疲惫还是不耐烦&#xff1f;是否想让一段客户反馈音频自…

作者头像 李华