Files
workspace/code/fms/.codebuddy/plans/field-name-sync-from-old-db_f94a2b08.md
T
2026-07-30 17:30:13 +08:00

5.1 KiB
Raw Blame History

name, overview, todos
name overview todos
field-name-sync-from-old-db 创建可复用的字段名同步服务,从旧库 s_columnLib.col_Caption 同步到新库 s_module_field.b_name,按视图名和字段名匹配,首批执行 v_b_othercompany。
id content status
fix-old-db-ssl 修复 g3hd-old.properties:移除 sslProtocol=TLSv1 参数,JDK 21 驱动自动协商 TLSv1.2 即可连通 completed
id content status dependencies
create-sync-service 新建 FieldNameSyncService.java:实现跨库 UPDATE SQL,按 viewName 匹配 s_columnLib,将 col_Caption 写入 s_module_field.b_name,不匹配字段不改动,返回更新行数 completed
fix-old-db-ssl
id content status dependencies
create-admin-controller 新建 AdminController.java,添加 POST /api/admin/sync-field-names 端点,JWT 认证,viewName 参数白名单校验,调用 FieldNameSyncService 并返回 ApiResponse completed
create-sync-service
id content status
add-sql-migration-ref 新建 023_sync_field_names.sql 参考脚本,记录跨库同步 SQL 作为纯 SQL 手动执行备选方案 completed

用户需求

构建一个可复用的工具,将旧库 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 版本供手动执行

数据流

  1. 前端/管理员发送 POST /api/admin/sync-field-names,请求体 { "viewName": "v_b_othercompany" }
  2. AdminController 校验 viewName 为合法标识符(字母/下划线/数字,最长128)
  3. FieldNameSyncService 通过 @Resource DataSource 获取新库连接
  4. 执行跨库 PreparedStatement UPDATE
  5. 返回 { "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 使用方式和现有异常处理/日志模式