5.1 KiB
5.1 KiB
name, overview, todos
| name | overview | todos | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| field-name-sync-from-old-db | 创建可复用的字段名同步服务,从旧库 s_columnLib.col_Caption 同步到新库 s_module_field.b_name,按视图名和字段名匹配,首批执行 v_b_othercompany。 |
|
用户需求
构建一个可复用的工具,将旧库 G3HY2025.dbo.s_columnLib 中存储的字段中文名称(col_Caption)同步到新库 fms.dbo.s_module_field.b_name。
匹配规则
s_module.b_viewtable=s_columnLib.col_TableName(模块视图名对应旧库表名)s_module_field.b_field=s_columnLib.col_FieldName(字段名精确匹配)- 匹配不上的字段,
b_name保持不变
首批同步目标
视图 v_b_othercompany
可复用要求
以后还有更多视图需要同步,工具须参数化视图名,方便批量复用。
技术方案
方案选择:跨库 SQL + 管理端点
核心决策:新旧库在同一 SQL Server 实例(118.89.70.199:1433),使用跨数据库 SQL 直接从新库连接执行 UPDATE ... FROM G3HY2025.dbo.s_columnLib,无需单独连接旧库。
UPDATE sf
SET sf.b_name = LTRIM(RTRIM(sc.col_Caption))
FROM dbo.s_module_field sf
JOIN dbo.s_module m ON m.b_id = sf.b_module_id
JOIN G3HY2025.dbo.s_columnLib sc
ON sc.col_TableName = m.b_viewtable
AND sc.col_FieldName = sf.b_field
WHERE m.b_viewtable = ?
AND sc.col_Caption IS NOT NULL
AND LTRIM(RTRIM(sc.col_Caption)) != '';
为何需要新端点而非复用通用端点:
- 通用
saveObjectApi只能操作当前 org 数据库的单表 insert/update/delete,无法表达跨库 JOIN 逻辑 - 通用
loadDataApi只能查询当前 org 的表,无法读取旧库s_columnLib - 此操作为管理类批量数据同步,不在业务 CRUD 范畴内
实现架构
flowchart LR
A[前端/管理员] -->|POST /api/admin/sync-field-names| B[AdminController]
B -->|校验 viewName 参数| C[FieldNameSyncService]
C -->|获取新库 Connection| D[OrgRoutingDataSource]
D -->|fms 连接| E[(SQL Server)]
E -->|跨库 JOIN| F[G3HY2025.dbo.s_columnLib]
E -->|UPDATE| G[fms.dbo.s_module_field]
C -->|返回同步数量| B
B -->|ApiResponse| A
模块划分
| 模块 | 文件 | 职责 |
|---|---|---|
| 配置修复 | config/dbconfigs/g3hd-old.properties |
移除 sslProtocol=TLSv1 |
| 同步服务 | service/FieldNameSyncService.java |
执行跨库 UPDATE,校验参数,返回影响行数 |
| 管理控制器 | controller/AdminController.java |
POST /api/admin/sync-field-names 端点,JWT 保护 |
| 参考脚本 | config/migrations/023_sync_field_names.sql |
纯 SQL 版本供手动执行 |
数据流
- 前端/管理员发送
POST /api/admin/sync-field-names,请求体{ "viewName": "v_b_othercompany" } AdminController校验viewName为合法标识符(字母/下划线/数字,最长128)FieldNameSyncService通过@Resource DataSource获取新库连接- 执行跨库 PreparedStatement UPDATE
- 返回
{ "updatedCount": 42, "message": "v_b_othercompany 同步完成,共更新 42 个字段名称" }
安全措施
viewName参数:白名单正则 `^[A-Za-z_][A-Za-z0-9_]{0,127},校验后作为 PreparedStatement 参数绑定(非字符串拼接)- JWT 认证:
AdminController路径/api/admin/**经JwtAuthFilter保护,仅登录用户可调用 - 失败不影响现有数据:UPDATE 在一条 SQL 内执行,单条匹配失败不阻断其他行
执行说明
- 热路径:单条 UPDATE SQL 跨库 JOIN,性能取决于
s_module_field行数和索引;对单个视图(~50 字段)毫秒级完成 - 日志:服务层记录同步开始/完成/失败日志,使用
@Slf4j,级别 INFO/ERROR - 事务:使用 Spring 声明式事务
@Transactional,确保整批同步原子提交或回滚 - 向后兼容:不修改现有
DataController和通用端点,不影响业务数据流
Agent Extensions
SubAgent
- code-explorer
- 目的:探索旧库连接方式、现有 Service/Controller 模式、参数校验惯例
- 预期结果:确认
OrgDataSourceManager的 API 使用方式和现有异常处理/日志模式