返回作品

SQL Server 迁移适配项目

创建于 2025 年 7 月 15 日

标签
  • Java
  • Spring Boot 2.5.15
  • Spring Security
  • MyBatis
  • MyBatis-Plus
  • PageHelper
  • Druid 1.2.23
  • SQL Server 2019
  • Microsoft JDBC
  • Redis
  • Vue 2
  • Element UI
  • Apache POI

项目介绍

SQL Server 迁移适配项目是一个基于若依 RuoYi-Vue 3.8.8 二次开发的加油站员工工资管理系统,业务原型是”按订单计算提成、按月核算工资”的薪酬管理后台。系统以四类销售订单(油品 orders、非油 order_other、开卡 order_card、重点单品 order_emphasis)为数据源头,员工工资按”站点(部门)+ 月份”组织:每月初自动或手动把上月有销售记录的员工同步成工资记录,随后按商品类别(香烟、重点商品、其他、D 类、92#/95#/98# 汽油、柴油、LNG)汇总销售额,套用 categorycategory_dept 两张提成系数表计算油品收入与非油提成,再叠加开卡收入、重点单品奖励、夜班与奖金、社保扣款等字段,最终输出每位员工当月的实发工资。

项目的核心工作是”迁移”:原系统数据层跑在 MySQL 上(ry_20240629.sql 若依基础库、gongzi.sql 工资业务库、quartz.sql 定时任务库三份脚本为 MySQL 8 导出),客户现场要求改用 SQL Server 2019(版本号 15.00.2000)。迁移后库名沿用 gongzi,schema 为 dbo,项目目录中保留了 dbo.sql 及 7 月 16、17、19 日连续三天的 SQL Server 增量导出版本(dbo25.7.16.sqldbo25.7.17.sqldbo25.7.19.sql),可见迁移过程中一边改脚本、一边按天出库对数据的迭代节奏。

项目架构

项目沿用若依经典的”前后端分离 + 后端多模块”结构,技术栈上最显著的变化是数据访问层同时使用 MyBatis 与 MyBatis-Plus:

模块技术栈说明
ruoyi-adminSpring Boot 2.5.15、Spring Security + JWT启动模块,端口 8081;web/controller/salary 下集中了员工工资、预估、订单、类别、月文件等业务控制器
ruoyi-commonMyBatis、fastjson2、Hutool、Apache POI通用层,分页工具 PageUtils 继承 PageHelperstartPage() 读取请求参数并交给 PageHelper 生成方言分页
ruoyi-systemMyBatis + MyBatis-Plus、PageHelper系统管理能力与工资业务:Mapper XML 位于 resources/mapper/systemDenserLngDayMonthFile 等实体使用 MyBatis-Plus 的 LambdaQueryWrapper 查询
ruoyi-frameworkDruid 1.2.23、Redis、Quartz数据源、安全过滤、Token 服务、定时任务框架设施
ruoyi-uiVue 2、Element UI、Axios管理后台前端,src/views/salary 下按业务组织工资、预估、订单等页面,开发代理指向 http://localhost:8081
sql/MySQL 8 + SQL Server 2019迁移前 MySQL 脚本(ry_20240629.sqlgongzi.sqlquartz.sql)与迁移后 SQL Server 导出版本(dbo.sqldbo25.7.*.sql)并存,便于对照

迁移适配的核心改动集中在三处:一是数据源配置,application-druid.yml 将驱动换为 com.microsoft.sqlserver.jdbc.SQLServerDriver,URL 改为 jdbc:sqlserver://;serverName=127.0.0.1;port=1433;databaseName=gongzi;二是分页方言,application.yml 中配置 pagehelper.helperDialect: sqlserver,让 PageHelper 自动生成 SQL Server 的 OFFSET/FETCH 分页语句;三是 SQL 脚本与 Mapper 语法的系统性改写。

核心功能

员工工资明细计算。 EmployeeSalaryController.calculateSalaryDetails 是工资核算的核心:对每条工资记录,以”上个月”为周期拉取该员工的油品与非油订单,按 category_name 分组累加销售额(92#/95#/98# 汽油、柴油、LNG 计入油品,香烟、重点商品、其他、D 类计入非油);油品部分根据部门当月销量区间从 category_dept 阶梯表取出对应提成系数相乘,再乘以 (100 - 预留比例) / 100 得到油品收入;LNG 提成需结合 lng_day 日销量表取系数,销量还要除以 denser 密度表中对应月份的密度再乘 1000 完成单位换算;最后汇总百元提成、开卡收入、重点单品收入、站长收入、奖金与社保,统一四舍五入到两位小数得出实发工资。

工资记录同步。 /salary/employee_salary/sync 按月同步:遍历上月油品、非油、开卡、重点单品四类订单,以 用户ID-站点编码-月份 为键去重,生成”员工-站点-月份”组合;对工资表中不存在的组合插入新记录(奖金、社保初始为 0),订单中出现而 sys_user 缺失的用户自动创建(用户名、昵称均为”未分配”),接口返回新增、更新与自动建号的数量;同步逻辑抽成了内部方法,注释中保留了每月 1 日凌晨 2 点定时执行的 Cron 写法,可手动触发也可接入调度任务。

下月工资预估。 YuGuController 复用同一套计算逻辑实现”预估”效果:查询时固定把月份设为当月,计算完成后将返回记录的 month 统一改写为下月(LocalDate.now().plusMonths(1)),于是列表呈现的是基于当前订单数据推算的下月工资预览,便于站点提前核对提成。

待分配工资统计。 /undistributed_salary 按站点统计待分配油品工资:从 sys_dept.reserved_percentage 读取部门预留比例(未设置时用默认值),计算预留工资与实发待分配额;站点编码缺省时取当前登录用户所属部门,月份缺省时取当前月,接口按”上月订单算待分配、当月工资算发放”的口径组织数据。

MySQL → SQL Server 2019 迁移适配。 这是项目区别于普通若依二次开发的核心内容,主要工作包括:

  • 建表脚本:AUTO_INCREMENT 主键改写为 IDENTITY(1,1)varchar/char 改写为 nvarchar/nchar(中文表字段使用 Chinese_PRC_CI_AS 排序规则),decimal(64,2) 等超宽精度收敛为 decimal(38,2)comment 注释改写为 sp_addextendedproperty 扩展属性,DROP TABLE IF EXISTS 改写为 IF EXISTS(SELECT ... FROM sys.all_objects ...) DROP TABLE,数据写入改为逐条 INSERT ... GO 批处理并包裹 BEGIN TRANSACTION/COMMIT,同步保留 SET IDENTITY_INSERT 以便还原原始主键;
  • Mapper 方言:取首条记录使用 select top 1(如 CategoryDeptMapper.getCommission 按区间取提成系数),日期比较使用 convert(VARCHAR(8), sales_time, 120) 截取到日,字符串包含判断使用 charindex(concat(',', #{deptId}), ancestors) > 0 替代 MySQL 的 LOCATE,业务统计中未再依赖 MySQL 特有的 DATE_FORMAT 等函数;
  • 代码层:部分查询从纯 XML 迁移到 MyBatis-Plus 的 LambdaQueryWrapper(如 DenserMapper 按月份查密度、LngDayMapper 按站点与月份查日销量),配合 mybatis-plus.typeAliasesPackage 等配置共存运行。

订单、类别与月文件管理。 系统提供油品、非油、开卡、重点单品四类订单的 CRUD 与按销售时间、销售人、站点筛选;category(商品类别提成)与 category_dept(站点阶梯提成区间)支持维护提成系数与销量区间;month_file 按月归档工资相关文件并支持 zip 打包下载,salary_award 维护奖励项目,前端另有 lng_day(LNG 日销量)页面支撑天然气提成核算。

功能截图

暂无运行截图。

快速上手

  1. 准备数据库:在 SQL Server 2019 上新建 gongzi 数据库(排序规则建议 Chinese_PRC_CI_AS),执行 sql/dbo25.7.19.sql(若依框架表、qrtz_* 调度表与全部业务表、演示数据均包含在内);需要对照迁移前后差异时可参考 sql/ry_20240629.sqlsql/gongzi.sqlsql/quartz.sql 三份 MySQL 原版脚本。

  2. 准备 Redis:本地启动 Redis(默认 6379),按 application.ymlspring.redis.database: 4 的配置选用库。

  3. 启动后端:

cd lianliang-sqlserver
# 修改 ruoyi-admin/src/main/resources/application-druid.yml 中的数据库地址、账号、密码
mvn clean package -DskipTests
java -jar ruoyi-admin/target/ruoyi-admin.jar
  1. 启动前端:
cd ruoyi-ui
npm install
npm run dev   # 默认 http://localhost:8080,接口代理到 8081
  1. 体验流程:在”系统管理-部门”确认站点编码与预留比例 → “工资管理”列表页选择月份搜索(工资明细自动按上月订单实时计算)→ 点击”工资同步”按月生成工资记录 → 打开”预估工资”查看基于当月订单的下月工资预览 → 在”订单管理”录入油品/非油/开卡/重点单品订单后重新查询,观察提成与实发工资的联动变化。

总结

SQL Server 迁移适配项目是一份很有参考价值的”数据库迁移 + 业务重构”案例:业务上,它是一个完整的加油站员工工资系统,以四类订单为源头、按月组织工资记录,通过阶梯提成系数、预留比例、密度换算等规则把销售额精确折算为员工实发工资,并具备自动同步、下月预估、待分配统计等贴近现场使用习惯的能力;技术上,项目完整走了一遍 MySQL → SQL Server 2019 的迁移路径——数据源驱动切换、PageHelper 分页方言切换、AUTO_INCREMENT/comment/sysdate()IDENTITY/sp_addextendedproperty/GETDATE() 的脚本转换、Mapper 层 top 1convertcharindex 等方言改写,同时引入 MyBatis-Plus 承担部分查询,还保留了 MySQL 原版脚本与逐日导出的 SQL Server 版本用于回归对照。对需要在若依(或同类 Spring Boot + MyBatis 脚手架)项目上完成跨数据库迁移、以及想了解加油站提成工资算法建模的开发者,这份代码与脚本集是现成的实战蓝本。