news 2026/6/26 14:23:42

基于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/23 14:51:57

PyCharm开发环境配置:Hunyuan-MT 7B Python SDK深度集成

PyCharm开发环境配置&#xff1a;Hunyuan-MT 7B Python SDK深度集成 1. 引言 作为一名长期使用PyCharm进行AI开发的工程师&#xff0c;我深知一个高效的开发环境对生产力有多重要。今天&#xff0c;我将带你一步步在PyCharm中配置Hunyuan-MT 7B的开发环境&#xff0c;这是一款…

作者头像 李华
网站建设 2026/6/22 16:33:42

技术拆解:通达信数据解析如何解决金融科技行业痛点

技术拆解&#xff1a;通达信数据解析如何解决金融科技行业痛点 【免费下载链接】mootdx 通达信数据读取的一个简便使用封装 项目地址: https://gitcode.com/GitHub_Trending/mo/mootdx 在金融科技领域&#xff0c;数据是驱动决策的核心引擎。通达信作为国内主流的证券分…

作者头像 李华
网站建设 2026/6/23 14:51:00

Cookie数据本地导出工具使用指南

Cookie数据本地导出工具使用指南 【免费下载链接】Get-cookies.txt-LOCALLY Get cookies.txt, NEVER send information outside. 项目地址: https://gitcode.com/gh_mirrors/ge/Get-cookies.txt-LOCALLY 如何在3分钟内完成Cookie导出工具的部署&#xff1f; 当你需要在…

作者头像 李华
网站建设 2026/5/28 19:16:29

Ollama+translategemma-4b-it:离线环境下的专业级翻译解决方案

Ollamatranslategemma-4b-it&#xff1a;离线环境下的专业级翻译解决方案 在没有网络连接、无法调用云端API、又对数据隐私高度敏感的场景中&#xff0c;你是否曾为一段技术文档、一份合同草稿、一张产品说明书的翻译而犯难&#xff1f;传统在线翻译工具受限于网络、语言支持范…

作者头像 李华
网站建设 2026/6/14 20:25:49

OFA英文语义分析:一键部署+开箱即用镜像体验

OFA英文语义分析&#xff1a;一键部署开箱即用镜像体验 1. OFA图像语义蕴含模型是什么 OFA图像语义蕴含模型&#xff08;iic/ofa_visual-entailment_snli-ve_large_en&#xff09;不是简单的图像分类器&#xff0c;也不是通用的图文理解模型&#xff0c;而是一个专门解决「视…

作者头像 李华
网站建设 2026/6/22 17:38:40

解锁NSC_BUILDER全能工具的隐藏潜力:Switch文件管理实战指南

解锁NSC_BUILDER全能工具的隐藏潜力&#xff1a;Switch文件管理实战指南 【免费下载链接】NSC_BUILDER Nintendo Switch Cleaner and Builder. A batchfile, python and html script based in hacbuild and Nuts python libraries. Designed initially to erase titlerights en…

作者头像 李华