业务扩展字段系统设计理念与流程图
一、设计理念
1. 核心目标
- 动态扩展性:支持业务字段无代码变更、实时生效
- 解耦性:字段定义与业务实体解耦,支持多业务线复用
- 可配置化:通过元数据配置字段类型、校验规则、展示逻辑
- 高性能:兼顾查询效率与存储灵活性
2. 设计原则
- 模块化:分离元数据管理、校验逻辑、存储引擎
- 开闭原则:新增字段类型无需修改核心代码
- 单一职责:每个模块仅处理特定功能(如校验、存储、查询)
- 容错性:数据校验失败时提供回滚机制,保障数据一致性
3. 技术选型依据
-
主表+动态扩展表:核心字段与扩展字段分离,平衡灵活性与查询性能
-
EAV模型优化:通过元数据表+值表实现动态字段,避免过度稀疏
-
JSON字段补充:复杂结构字段使用JSON存储,兼顾可读性与扩展性
-
策略模式+工厂模式:动态选择字段处理器,支持类型扩展
二、系统架构设计
三、关键设计细节
1. 元数据管理
-
字段定义表:存储字段编码、类型、校验规则、状态等
CREATE TABLE IF NOT EXISTS `TRANSFER_BIZ_EXTEND_FIELD` (`ID` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',`BIZ_MODULE` VARCHAR(64) NOT NULL COMMENT '所属业务模块(如:CREATE/CHANGE_UPRIGHT/CHANGE)',`BIZ_ENTITY_TYPE` VARCHAR(64) NOT NULL COMMENT '关联业务实体类型(如:TN_CONTRACT_TRANSFER/TN_CONTRACT_TRANSFER_ATTACH)',`FIELD_CODE` VARCHAR(64) NOT NULL COMMENT '字段编码(唯一标识,如:IS_HANGING_COMPONENT)',`FIELD_NAME` VARCHAR(128) NOT NULL COMMENT '字段名称',`DESCRIPTION` VARCHAR(256) DEFAULT NULL COMMENT '字段描述',`DATA_TYPE` VARCHAR(32) NOT NULL COMMENT '数据类型(枚举:STRING/INT/DECIMAL/DATETIME/TEXT/BOOLEAN/JSON)',`LENGTH` INT UNSIGNED DEFAULT 255 COMMENT '字符串/文本类型长度限制(仅STRING/TEXT有效)',`PRECISION` INT UNSIGNED DEFAULT 19 COMMENT '数值类型总位数(仅DECIMAL有效,如DECIMAL(19,4)的19)',`SCALE` INT UNSIGNED DEFAULT 4 COMMENT '数值类型小数位数(仅DECIMAL有效,如DECIMAL(19,4)的4)',`IS_REQUIRED` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否必填(0-非必填,1-必填)',`DEFAULT_VALUE` VARCHAR(512) DEFAULT NULL COMMENT '默认值(需与DATA_TYPE匹配)',`IS_SEARCHABLE` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否可搜索(0-否,1-是)',`IS_FILTERABLE` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否可筛选(0-否,1-是)',`IS_SORTABLE` TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '是否可排序(0-否,1-是)',`STATUS` TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '字段状态(0-禁用,1-启用)',`EXT_CONFIG` JSON DEFAULT NULL COMMENT '扩展配置(如校验规则、联动逻辑)',`CREATE_TIME` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`UPDATE_TIME` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',`CREATOR` VARCHAR(64) NOT NULL COMMENT '创建人(用户ID/账号)',`UPDATER` VARCHAR(64) NOT NULL COMMENT '更新人(用户ID/账号)',PRIMARY KEY (`ID`),UNIQUE KEY `UNIQ_FIELD_CODE` (`FIELD_CODE`), -- 字段编码全局唯一INDEX `IDX_BIZ_MODULE_ENTITY` (`BIZ_MODULE`, `BIZ_ENTITY_TYPE`), -- 按业务模块+实体类型快速查询INDEX `IDX_STATUS` (`STATUS`) -- 按状态过滤启用字段) ENGINE=INNODB DEFAULT CHARSET=UTF8MB4 COLLATE=UTF8MB4_UNICODE_CI COMMENT='合同业务扩展字段元数据表';
-
扩展值表:存储动态字段值,支持JSON格式
CREATE TABLE IF NOT EXISTS `TRANSFER_BIZ_EXTEND_VALUE` (`ID` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID',`BIZ_MODULE` VARCHAR(64) NOT NULL COMMENT '所属业务模块(与TRANSFER_BIZ_EXTEND_FIELD.BIZ_MODULE一致)',`BIZ_ENTITY_TYPE` VARCHAR(64) NOT NULL COMMENT '关联业务实体类型(与TRANSFER_BIZ_EXTEND_FIELD.BIZ_ENTITY_TYPE一致)',`BIZ_ENTITY_ID` BIGINT UNSIGNED NOT NULL COMMENT '业务实体ID(如合同ID)',`FIELD_CODE` VARCHAR(64) NOT NULL COMMENT '字段编码(与TRANSFER_BIZ_EXTEND_FIELD.FIELD_CODE一致)',`FIELD_VALUE` TEXT COMMENT '字段实际值(根据DATA_TYPE解析)',`CREATE_TIME` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',`UPDATE_TIME` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '最后更新时间',PRIMARY KEY (`ID`),-- 组合索引:快速查询某个业务实体的所有扩展字段(高频操作)INDEX `IDX_ENTITY` (`BIZ_MODULE`, `BIZ_ENTITY_TYPE`, `BIZ_ENTITY_ID`),-- 唯一约束:防止同一实体同一字段重复存储(可选,根据业务需求)UNIQUE KEY `UNIQ_ENTITY_FIELD` (`BIZ_MODULE`, `BIZ_ENTITY_TYPE`, `BIZ_ENTITY_ID`, `FIELD_CODE`)) ENGINE=INNODB DEFAULT CHARSET=UTF8MB4 COLLATE=UTF8MB4_UNICODE_CI COMMENT='合同业务扩展字段值存储表';
2. 动态校验流程
3. 查询优化策略
-
索引优化:对高频查询字段建立覆盖索引
CREATE INDEX idx_entity_field ON biz_extend_value (entity_id, field_code);
-
缓存策略:使用Redis缓存字段元数据(TTL=5分钟)
-
混合查询:简单条件走数据库,复杂条件走Elasticsearch
四、设计模式应用
1. 策略模式
-
场景:不同数据类型(字符串/数值/日期)的解析与校验
-
实现:通过
FieldValueHandler
接口统一处理public class FieldHandlerFactory {// 静态映射表,用于存储数据类型与字段值处理器的对应关系private static final Map<String, FieldValueHandler> handlers = new HashMap<>();// 静态初始化块,用于初始化映射表,将数据类型字符串与对应的处理器实例进行映射static {handlers.put(FieldDataTypeEnum.STRING.name(), new StringHandler());}/*** 根据数据类型获取对应的字段值处理器** @param dataType 数据类型,是一个字符串,用于指定需要的处理器类型* @return 返回对应数据类型的FieldValueHandler实例,如果指定的数据类型不存在,则返回null*/public static FieldValueHandler getHandler(String dataType) {return handlers.get(dataType);}}
2. 工厂模式
-
场景:根据字段类型动态创建处理器实例
-
实现:
FieldHandlerFactory
管理处理器池/*** FieldHandlerFactory 类用于根据数据类型提供相应的字段值处理器* 该工厂类通过一个静态映射表来管理不同数据类型的处理器,以实现根据输入的数据类型返回对应的处理器实例*/ public class FieldHandlerFactory {// 静态映射表,用于存储数据类型与字段值处理器的对应关系private static final Map<String, FieldValueHandler> handlers = new HashMap<>();// 静态初始化块,用于初始化映射表,将数据类型字符串与对应的处理器实例进行映射static {handlers.put(FieldDataTypeEnum.STRING.name(), new StringHandler());}/*** 根据数据类型获取对应的字段值处理器** @param dataType 数据类型,是一个字符串,用于指定需要的处理器类型* @return 返回对应数据类型的FieldValueHandler实例,如果指定的数据类型不存在,则返回null*/public static FieldValueHandler getHandler(String dataType) {return handlers.get(dataType);}}
3. 模板方法模式
-
场景:统一字段处理流程(解析→校验→存储)
-
实现:抽象类定义骨架,子类实现具体步骤
public interface FieldValueHandler {/*** 解析原始字符串值为特定的对象类型** @param rawValue 待解析的原始字符串值* @return 解析后的对象,具体类型取决于实现*/Object parseValue(String rawValue, String defaultValue);/*** 验证给定的值是否满足特定的条件或格式** @param value 待验证的值* @return 如果值有效则返回true,否则返回false*/boolean validate(Object value, TransferBizExtendField field);/*** 将给定的值格式化为字符串形式** @param value 待格式化的值* @return 格式化后的字符串*/String formatValue(Object value); }
五、设计流程图
六、技术优势
- 扩展性:新增字段类型只需实现
FieldValueHandler
,无需修改核心代码 - 性能:
- 扩展字段值采用JSON压缩存储(节省空间)
- 热点数据预加载至Redis(查询延迟)
- 安全性:
- 敏感字段自动加密(如用户手机号)
- 字段级权限控制(控制暴露范围)