字段元数据
字段元数据是模型字段的描述信息的集合,它定义了该模型在业务场景中用到的各种字段,以及每个字段的类型、长度、默认值、必填、只读、关联关系等等。通过这些元数据,系统可以按照统一的模式控制数据的响应、处理和交互,同时也可以对通用需求进行抽象处理,确保数据的一致性、准确性和完整性。
1、字段类型介绍
| 序号 | 类型 | 类型名称 | 默认值 | 描述 |
|---|---|---|---|---|
| 1 | String | 字符串 | "" | 通过 length 配置字符串长度。 |
| 2 | Integer | 整数 | 0 | 通过 length 配置整数位数。 |
| 3 | Long | 长整数 | 0L | |
| 4 | Double | 小数 | 0.00 | 普通小数,用于可接受精度损失的计算场景。 |
| 5 | BigDecimal | 精确小数 | ”0” | 用于金额、货币、汇率等高精度计算场景。 |
| 6 | Boolean | 布尔字段 | false | |
| 7 | Date | 日期字段 | 格式 yyyy-MM-dd,如 2025-02-14 | |
| 8 | DateTime | 日期时间 | 格式 yyyy-MM-dd HH:mm:ss,如 2024-02-29 19:15:20 | |
| 9 | Option | 单选字段 | ||
| 10 | MultiOption | 多选字段 | [] | |
| 11 | MultiString | 字符串列表 | [] | |
| 12 | File | 单个文件 | 虚拟字段,上传并绑定一个文件 | |
| 13 | MultiFile | 多个文件 | 虚拟字段,上传并绑定多个文件 | |
| 14 | JSON | JSON | JSON字符串存储 | |
| 15 | Filters | 筛选条件 | 存储中缀表达式筛选条件 | |
| 16 | Orders | 排序条件 | 存储多字段排序条件 | |
| 17 | OneToOne | 一对一 | 配置 relatedModel | |
| 18 | ManyToOne | 多对一 | 配置 relatedModel | |
| 19 | OneToMany | 一对多 | 虚拟字段,配置 relatedModel + relatedField | |
| 20 | ManyToMany | 多对多 | 虚拟字段,配置 relatedModel + jointModel + jointLeft + jointRight |
备注: 1. OneToOne、ManyToOne、OneToMany、ManyToMany 字段涉及到的外键为逻辑外键,非数据库物理外键。 2. 虚拟字段,在当前数据表中并不存在,操作虚拟字段时,框架自动进行相关处理。
需要补充说明的字段类型如下:
1.1 Date 日期
代码中为 LocalDate 对象,展示格式为 yyyy-MM-dd ,如 2024-02-29 。
1.2 DateTime 日期时间
适用于精确到秒的日期时间类型,代码中为 LocalDateTime 对象,数据库中存储为时间戳,展示格式为 yyyy-MM-dd HH:mm:ss ,如 2024-02-29 19:15:20 。
1.3 Option 单选
单选字段,必须配置 OptionCode 属性,即选项集编码。
在保存单选字段的值时,实际传递和存储的是选项条目的编码。
API 获取单选字段的值时,默认返回 [itemCode, itemName] 格式,也即同时返回条目的编码和名称。
选项集的配置和使用,具体参考 选项集 章节
1.4 MultiOption 多选
多选字段跟单选字段的区别是,多选字段允许从同一个选项集中,选择多个选项,保存时传递选项的编码字符串列表,并在数据库中存储的多个选项条目的编码,使用 , 间隔。
API 读取多选字段的值时,默认返回 [[itemCode, itemName], ... ] 格式,也即多个选项的编码和名称。
1.5 MultiString 字符串列表
适用于通过单字段存储多个字符串值,程序中处理字符串列表对象,在数据库中使用 , 间隔存储。
1.6 File File 字段
该字段类型,用于上传和绑定一个文件。文件自动存储在 FileRecord 模型。
1.7 MultiFile MultiFile 字段
该字段类型,用于上传和绑定多个文件。文件自动存储在 FileRecord 模型。
1.8 JSON JSON 字段
JSON 格式字段,一般仅用于 JSON 数据存储和对象转换。需要针对 JSON 数据进行索引和条件查询时,需要手工处理。
1.9 Filter 筛选条件字段
仅用于存储筛选条件对象 Filters 的 JSON 字符串。
1.9 Orders 筛选条件字段
仅用于存储排序条件对象 Orders 的 JSON 字符串。
1.10 OneToOne 一对一
关系型字段,需配置 relatedModel 和 relatedField 属性。选择的数据具有唯一性。
1.11 ManyToOne 多对一
关系型字段,需配置 relatedModel 和 relatedField 属性。
1.12 OneToMany 一对多
OneToMany 字段的数据,一般在客户端针对单条数据进行新增、编辑、删除,调用 Many 端的模型接口即可。
针对批量编辑 OneToMany 字段值的场景:
(1)字段值为 [],空列表表示全部删除历史记录
(2)字段值不为空时, [{...}, {...}] 即 Many 端的数据列表结构时,自动识别出 Many 端的新增、编辑和删除的记录,并进行相应的处理。
1.13 ManyToMany 多对多
(1) ManyToMany 字段的更新
在 Create/Update 场景中,ManyToMany 字段的值传参关联模型的 id 列表。如 Update 请求:
{
"id": 12,
"attendeeIds": [1, 2, 3]
}程序自动识别被删除的关系。
(2) ManyToMany 字段的级联搜索
应用场景:通过关联表字段的筛选条件,过滤当前表的数据。具体参考 查询条件 章节。
2、字段元数据属性
| 序号 | 字段信息 | 数据类型 | 描述 | 备注 |
|---|---|---|---|---|
| 1 | labelName | String | 字段标签 | |
| 2 | modelName | String | 模型名 | |
| 3 | fieldName | String | 字段名 | |
| 4 | fieldType | Option | 字段类型 | |
| 5 | optionCode | String | 选项集编码 | |
| 6 | defaultValue | String | 字段默认值 | |
| 7 | length | Integer | 字段长度 | |
| 8 | scale | Integer | 小数位数 | |
| 9 | required | Boolean | 必填字段,默认 false | |
| 10 | readonly | Boolean | 只读字段,默认 false | |
| 11 | hidden | Boolean | 是否隐藏,默认 false | |
| 12 | copyable | Boolean | 可复制字段,默认 true | |
| 13 | searchable | Boolean | 可搜索字段,默认 true | |
| 14 | dynamic | Boolean | 动态字段,默认 false | |
| 15 | translatable | Boolean | 可翻译字段,默认 false | |
| 16 | encrypted | Boolean | 加密字段,默认 false | |
| 17 | maskingType | Option | 脱敏类型 | |
| 18 | computed | Boolean | 计算型字段,默认 false | |
| 19 | expression | String | 计算表达式 | |
| 20 | cascadedField | String | 级联字段 | 关系属性 |
| 21 | relatedModel | String | 关联模型 | 关系属性 |
| 22 | relatedField | String | 关联字段 | OneToMany 的 Many 端字段名 |
| 23 | jointModel | String | ManyToMany 连接模型 | 中间模型 |
| 24 | jointLeft | String | 连接模型左侧字段名 | 存储左侧模型外键 |
| 25 | jointRight | String | 连接模型右侧字段名 | 存储右侧模型外键 |
| 26 | filters | String | 关系型字段过滤条件 | 关系属性 |
| 27 | columnName | String | 数据表列名 | 只读 |
| 28 | description | String | 字段描述 |
2.1 labelName 字段标签
字段的标签名称,也即字段的语义化名称,通常作为显示在列表页表头或表单页的字段名称。如 联系电话 。
2.2 modelName 模型名
字段所属的模型名,这里的模型名是指模型的技术名称,如 ProductCategory 。
2.3 fieldName 字段名
字段的技术名称,使用小驼峰命名,对应实体类的属性名称定义,如 unitPrice。在查询前,会根据存储类型对字段名进行转换,将字段名转换成 下划线命名 ,如 unit_price。
2.4 fieldType 字段类型
系统预置的字段类型,包括字符串文本、多种数值类型、日期类型、选项集类型、JSON 类型,以及多种关系类型等,详见 字段类型 FieldType 小结。
2.5 optionCode 选项集编码
选项集一般应用于选项相对固定、选项数量有限,但又需要支持扩展的的业务场景。在 OpenMeta 中,所有的选项信息存储在 选项集模型和 选项集条目模型 中。
当字段类型为 单选 或 多选 时,需要配置字段的 optionCode 选项集编码属性。
2.6 defaultValue 字段默认值
字段的默认值配置,在创建新记录时,如果当前字段没有被赋值,将使用默认值填充。
Create 场景下默认值的赋值逻辑:
(1)判断字段是否有值(非 NULL),有值则使用当前值,不再使用默认值。如文本字段的空字符串 “ 也算是有值,数值字段的 0 也是有值。
(2)当前字段没有被赋值时,优先使用默认值填充。
(3)如果字段未配置默认值时,则采用字段类型对应的默认值,具体参考下文 字段类型 FieldType ,不同字段类型对应的全局默认值。
2.7 length 字段长度
字段的长度,对应于字符串类型的字符长度,以及整数类型、高精度数值类型的数字位数。
2.8 scale 小数位数
浮点数类型、高精度数值类型的小数位数,默认小数位数为 2 位。
2.9 required 必填字段
字段的必填属性控制,在 OpenMeta 的数据处理程序层面就会立即进行校验,不依赖数据库进行控制。当 create 或 update 数据时检查字段的必填属性,与数据库的 not null 属性不同,数据库的not null 字段可以有默认值不一定是必填,OpenMeta 字段的 required 控制逻辑比数据库的 not null 更加严格,required=true 的字段,在创建时必须赋值,且值不能为空(包括空字符串也不被允许),更新该字段时,也不能置空。
2.10 readonly 只读字段
是否允许客户端更新。readonly=true 的字段,不允许客户端/API赋值、更新该字段,仅支持服务端更新,如计算型字段或自动填充字段。客户端创建和更新数据时检查字段的该属性,给只读字段赋值时会报错。
审计字段 createdId、createdTime、updatedId、updatedTime 的值由底层自动维护,默认即 readonly=true。
2.11 hidden 是否隐藏
是否在客户端默认隐藏该字段,默认为 false ,即不隐藏。
2.12 copyable 可复制字段
在客户端对数据进行复制时,是否复制当前字段的数据,默认为 true ,即所有字段都是可复制的,主键 id 字段除外。
2.13 searchable 可搜索字段
在通用搜索场景中,该字段是否可以作为查询条件。默认为 true ,即所有字段都是可搜索的。
2.14 dynamic 动态字段
该字段是否为动态字段,默认 false,程序运行时自动计算动态字段的值,该值不存储在数据库中。
可为 true 的场景:动态计算字段、动态级联字段,动态字段的值一般代表最新数据的计算结果值,使用动态计算字段时,需要考虑对客户端性能的影响。
2.15 translatable 可翻译字段
在数据多语言场景中,表示当前字段的值是否可翻译,translatable=true 表示当前字段是多语言字段。默认为 false 。
2.16 encrypted 加密字段
该字段是否为加密字段,默认使用 AES256 加密。
2.17 maskingType 脱敏类型
当该字段为敏感数据时,配置的数据脱敏类型,可按照手机号、姓名、身份证号、银行卡号规则脱敏等等。
客户端通过 API 获取数据时,程序会自动对该字段的数据进行脱敏处理。脱敏方式可以配置为将字段的全部或部分数据替换为 **** 字符串。
脱敏字段不影响级联字段、计算型字段这些在服务端计算处理的字段类型,也即计算型字段可以依赖脱敏字段,或计算型字段同时也是脱敏字段。
客户端可以通过 getUnmaskedField 接口获取指定字段的敏感数据,在此过程中,服务端将记录敏感数据的访问日志。
All: 全部脱敏,全部替换为****。Name:名称脱敏,保留首尾各 1 个字符,当名称只有 2 个字符时,保留最后 1 个字符。Email:邮箱脱敏,保留前 4 位字符。PhoneNumber:电话号码脱敏,对后 4 位字符进行脱敏。IdNumber:证件号脱敏,保留首尾各 4 位字符。CardNumber:卡号码脱敏,保留末尾 4 位字符。
2.18 computed 计算型字段
表示该字段是否为计算型字段。计算型字段可配置计算表达式,并在计算表达式中依赖当前模型的其它字段。
目前出于性能考虑,不支持在单个计算表达式中跨模型引用字段,如有需要,可以在 Flow 编排中跨模型读取字段数据并参与计算。
dynamic=false 的计算型字段,当依赖的字段发生变化时,自动触发重新计算。
dynamic=true 的计算型字段,表示计算结果并不存储在数据库中,当读取该计算型字段时,自动执行计算。
2.19 expression 计算表达式
在 expression 表达式中,可以引用当前模型的其它字段进行计算。在表达式中,可以进行四则运算,调用字符串函数、日期函数等常用工具函数。
对于数值类型,默认采用高精度计算避免精度损失,计算过程中保留 16 位小数,末尾采用 银行家舍入法。由于数值字段的小数位数参数配置一般小于等于 16 位,因此该计算过程的精度不影响字段本身的精度控制。
OpenMeta 引用了 AviatorScript 作为表达式引擎,并设置为安全沙箱模式。
2.20 cascadedField 级联字段
通过 OneToOne/ManyToOne 字段引用关联模型的字段值,配置格式为点号间隔的级联字段,左侧为当前模型的 OneToOne/ManyToOne 字段名,右侧为关联模型的字段名,如 productId.productName。
dynamic=false 的级联字段,当依赖的 OneToOne/ManyToOne 字段发生变化时,自动触发重新计算。
dynamic=true 的级联字段,表示级联值并不存储在数据库中,当读取该级联字段时,自动级联读取最新的字段值。
此级联为逻辑级联,非数据库级联。仅 OneToOne/ManyToOne 字段支持级联取值。
2.21 relatedModel 关联模型
关系型字段的关联模型,即 OneToOne、ManyToOne、OneToMany、ManyToMany 字段类型的关联模型名。
2.22 relatedField 关联字段
- 当字段类型为 OneToMany 时,填写关联模型中存储当前模型外键的字段名,且不能为空。
- OneToOne、ManyToOne 时默认该属性为关联模型的
id。
2.23 jointModel ManyToMany 连接模型
当字段类型为 ManyToMany 时,jointModel 不能为空。jointModel 配置的是连接模型,也即中间模型,存储的是左右两个模型的映射关系数据。
在查询时,先到 jointModel 连接模型查询映射关系数据,再到 relatedModel 查询关联模型的字段数据,从而实现多对多关系的查询。
默认值规则:根据左右两个模型名,以及 Rel 标识,自动拼接生成连接模型名,如 User + Role + Rel = UserRoleRel。
2.24 jointLeft 连接模型左侧字段名
当字段类型为 ManyToMany 时,配置连接模型存储左侧模型外键的字段名。
默认值规则:将左侧模型名首字母转换为小写,再拼接 Id ,如 User + Id = userId。
2.25 jointRight 连接模型右侧字段名
当字段类型为 ManyToMany 时,配置连接模型存储右侧模型外键的字段名。
默认值规则:将右侧模型名首字母转换为小写,再拼接 Id ,如 Role + Id = roleId。
2.26 filters 关系型字段过滤条件
针对 OneToOne、ManyToOne 关系型字段的基础筛选条件,用于根据业务场景对可选数据进行过滤,客户端在执行查询时可携带的固定筛选条件,与用户搜索条件是 AND 关系。
2.27 columnName 数据表列名
只读字段,字段对应的数据表列名,由字段名自动转换,如 unit_price。
字段名变化时,默认同步修改数据表列名。可以通过全局 DDL 开关配置关闭自动修改数据表,以满足通过其它方式提交 DDL 的场景。
2.28 description 字段描述
字段的业务描述。