news 2026/6/10 16:28:20

基于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/6/10 10:24:28

3步打造电影级Minecraft画面:Revelation光影包零基础指南

3步打造电影级Minecraft画面&#xff1a;Revelation光影包零基础指南 【免费下载链接】Revelation A realistic shaderpack for Minecraft: Java Edition 项目地址: https://gitcode.com/gh_mirrors/re/Revelation Revelation光影包是一款为Minecraft: Java Edition设计…

作者头像 李华
网站建设 2026/6/10 10:20:28

如何修改图片路径?万物识别脚本调试技巧揭秘

如何修改图片路径&#xff1f;万物识别脚本调试技巧揭秘 本文聚焦于「万物识别-中文-通用领域」镜像在真实调试过程中的高频痛点——图片路径错误导致推理失败。这不是一篇泛泛而谈的部署指南&#xff0c;而是一份来自一线实操的“排障手记”&#xff1a;从路径报错的典型现象…

作者头像 李华
网站建设 2026/6/9 22:45:45

微信聊天记录永久保存:用情感资产守护你的数字记忆

微信聊天记录永久保存&#xff1a;用情感资产守护你的数字记忆 【免费下载链接】QZoneExport QQ空间导出助手&#xff0c;用于备份QQ空间的说说、日志、私密日记、相册、视频、留言板、QQ好友、收藏夹、分享、最近访客为文件&#xff0c;便于迁移与保存 项目地址: https://gi…

作者头像 李华
网站建设 2026/6/10 10:23:17

Lychee多模态重排序模型企业应用:电商图文匹配、教育题库检索落地解析

Lychee多模态重排序模型企业应用&#xff1a;电商图文匹配、教育题库检索落地解析 1. 项目背景与核心价值 在当今信息爆炸的时代&#xff0c;如何从海量数据中快速准确地找到最相关的内容成为企业面临的重要挑战。Lychee多模态重排序模型正是为解决这一痛点而生&#xff0c;它…

作者头像 李华
网站建设 2026/6/10 10:38:20

免费体验:MedGemma X-Ray医疗影像分析系统快速入门

免费体验&#xff1a;MedGemma X-Ray医疗影像分析系统快速入门 你是否曾想过&#xff0c;一张普通的胸部X光片&#xff0c;也能被AI像资深放射科医生一样逐层“阅读”&#xff1f;不需要复杂配置、不依赖专业GPU服务器、不写一行代码——只需几分钟&#xff0c;你就能在浏览器…

作者头像 李华
网站建设 2026/6/10 10:40:24

告别直播音频困扰:用OBS-VST插件实现专业级直播音频优化

告别直播音频困扰&#xff1a;用OBS-VST插件实现专业级直播音频优化 【免费下载链接】obs-vst Use VST plugins in OBS 项目地址: https://gitcode.com/gh_mirrors/ob/obs-vst 作为内容创作者&#xff0c;你是否曾遇到这些直播音频问题&#xff1a;明明使用了不错的麦克…

作者头像 李华