查看 代码示例
Yao 可以读取数据模型定义,实现数据迁移、元数据原子操作、元数据输入校验和元数据管理后台。元数据原子操作方法被映射为处理器(process
),支持模型间数据关系映射,可在数据流(Flow
)和接口(API
)中访问查询。如采用golang
语言开发业务插件(Plugin
),可以使用 Package Gou
访问模型的各个方法, 后续将提供 NodeJS
等语言 SDK。一个数据模型对应数据库中的一张数据表, 通过 JSON 文件描述数据表结构,放置在models
目录中。使用 yao migrate
命令创建/更新数据表结构设计。
处理器 | 说明 | 文档 |
---|---|---|
models.<模型名称>.Find | 查询单条记录 | 查看 |
models.<模型名称>.Get | 按条件查询, 不分页 | 查看 |
models.<模型名称>.Paginate | 按条件查询, 分页 | 查看 |
models.<模型名称>.Create | 创建单条记录, 返回新创建记录 ID | 查看 |
models.<模型名称>.Update | 更新单条记录 | 查看 |
models.<模型名称>.Save | 保存单条记录, 不存在创建记录, 存在更新记录, 返回记录 ID | 查看 |
models.<模型名称>.Delete | 删除单条记录(标记删除) | 查看 |
models.<模型名称>.Destroy | 删除单条记录(真删除) | 查看 |
models.<模型名称>.Insert | 插入多条记录, 返回插入行数 | 查看 |
models.<模型名称>.UpdateWhere | 按条件更新记录, 返回更新行数 | 查看 |
models.<模型名称>.DeleteWhere | 按条件删除数据, 返回删除行数(标记删除) | 查看 |
models.<模型名称>.DestroyWhere | 按条件删除数据, 返回删除行数(真删除) | 查看 |
models.<模型名称>.EachSave | 保存多条记录, 不存在创建记录, 存在更新记录, 返回记录 ID 集合 | 查看 |
models.<模型名称>.EachSaveAfterDelete | 删除一组给定 ID 的记录后,保存多条记录, 不存在创建, 存在更新, 返回 ID 集合 | 查看 |
数据模型描述文件是以 小写英文字母 命名的 JSON 文本文件 <name>.mod.yao
文件夹 (相对应用模型根目录) | 文件名 | 模型名称 | Process (在 API /Flow 中引用) |
---|---|---|---|
/ | name.mod.yao | name | models.name.<process> |
/group/ | name.mod.yao | gorup.name | models.gorup.name.<process> |
/group1/group2/ | name.mod.yao | gorup1.gorup2.name | models.gorup1.group2.name.<process> |
{"name": "用户","table": {},"columns": [],"indexes": [],"relations": {},"values": [],"option": {}}
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 模型中文名称 | 是 |
table | Object | 数据表定义 | 是 |
columns | Array\<Object> | 字段定义 | 是 |
indexes | Array\<Object> | 索引定义 | 是 |
relations | [key:String]:Object | 关系映射 | 否 |
values | Array\<Object> | 默认数据 | 否 |
option | Object | 配置选型 | 否 |
数据表格包含 name
、comment
等字段,定义模型存储在数据库中的数据表名称、注释等信息。支持 MySQL
, PostgreSQL
、SQLite
等 Xun Database
或第三方提供驱动的数据库。
{"table": {"name": "user","comment": "用户表","engine": "InnoDB"}}
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 数据表名称 | 是 |
comment | String | 数据表注释中文名 | 否 |
engine | String | 数据表引擎(MySQL ONLY) 许可值 InnoDB , MyISAM | 否 |
columns
一个模型可以包含多个字段定义,每个字段定义包含 label
、name
、type
、 validations
等信息。
{"columns": [{ "label": "ID", "name": "id", "type": "ID" },{"label": "厂商","name": "manu_id","type": "bigInteger","length": 50,"comment": "所属厂商","nullable": true,"index": true,"validations": [{"method": "typeof","args": ["integer"],"message": "{{input}}类型错误, {{label}}应为数字"},{"method": "min","args": [0],"message": "{{label}}应大于0"}]},{"label": "手机号","name": "mobile","type": "string","length": 50,"comment": "手机号","index": true,"crypt": "AES","validations": [{"method": "typeof","args": ["string"],"message": "{{input}}类型错误, {{label}}应该为字符串"},{"method": "pattern","args": ["^1[3-9]\\d{9}$"],"message": "{{input}}格式错误"}]}]}
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 字段名称,对应数据表中字段名称 | 是 |
type | String | 字段类型, | 是 |
label | String | 字段显示名称,用于在管理表单,开发平台等成场景下呈现 | 是 |
comment | String | 字段注释,对应数据表中字段注释 | 否 |
title | String | 字段标题,可用于开发平台中呈现 | 否 |
description | String | 字段介绍,可用于开发平台中呈现 | 否 |
length | Integer | 字段长度,对 string 等类型字段有效 | 否 |
precision | Integer | 字段位数(含小数位),对 float 、decimal 等类型字段有效 | 否 |
scale | Integer | 字段小数位位数,对 float 、decimal 等类型字段有效 | 否 |
option | Array\<String> | 字段许可值,对 enum 类型字段有效 | 否 |
default | String|Integer|Float | 字段默认值 | 否 |
default_raw | String | 字段默认值,支持数据库函数,如 NOW() default 和 default_raw 同时存在 default_raw 优先级高 | 否 |
crypt | String | 字段加密存储方式(MySQL Only)。许可值 AES , PASSWORD | 否 |
nullable | Bool | 字段是否可以为空,默认为 false | 否 |
index | Bool | 字段是否为索引,默认为 false | 否 |
unique | Bool | 字段是否为唯一索引,默认为 false , 如为 true 无需同时将 index 设置为 true | 否 |
primary | Bool | 字段是否为主键,每张表至多一个主键字段。默认为 false | 否 |
validations | Array\<Object> | 字段校验规则 | 否 |
类型 | 说明 | 可选参数 | MySQL 字段类型 |
---|---|---|---|
string | 字符串 | length | VARCHAR(length ) |
char | 字符 | length | CHAR (length ) |
text | 文本 | TEXT | |
mediumText | 中文本 | MEDIUMTEXT | |
longText | 长文本 | LONGTEXT | |
binary | 二进制数据 | VARBINARY | |
date | 日期 | DATE | |
datetime | 日期时间 | length | DATETIME |
datetimeTz | 带时区的日期时间 | length | DATETIME |
time | 时间 | length | TIME |
timeTz | 带时区的时间 | length | TIME |
timestamp | 时间戳 | length | TIMESTAMP |
timestampTz | 带时区的时间戳 | length | TIMESTAMP |
tinyInteger | 微整型 | TINYINT | |
tinyIncrements | 无符号微整型+自增 | TINYINT UNSIGNED AUTO_INCREMENT | |
unsignedTinyInteger | 无符号微整型 | TINYINT UNSIGNED | |
smallInteger | 小整型 | SMALLINT | |
smallIncrements | 无符号小整型+自增 | SMALLINT UNSIGNED AUTO_INCREMENT | |
unsignedSmallInteger | 无符号小整型 | SMALLINT UNSIGNED | |
integer | 整型 | INT | |
increments | 无符号整型+自增 | INT UNSIGNED AUTO_INCREMENT | |
unsignedInteger | 无符号整型 | INT UNSIGNED | |
bigInteger | 长整型 | BIGINT | |
bigIncrements | 无符号长整型+自增 | BIGINT UNSIGNED AUTO_INCREMENT | |
unsignedBigInteger | 无符号长整型 | BIGINT UNSIGNED | |
id | 长整型+自增 | BIGINT UNSIGNED AUTO_INCREMENT | |
ID | 长整型+自增(同 id) | BIGINT UNSIGNED AUTO_INCREMENT | |
decimal | 小数(一般用于存储货币) | precision 、scale | DECIMAL(precision ,scale ) |
unsignedDecimal | 无符号小数 (一般用于存储货币) | precision 、scale | DECIMAL (precision ,scale ) UNSIGNED |
float | 浮点数 | precision 、scale | FLOAT (precision ,scale ) |
unsignedFloat | 无符号浮点数 | precision 、scale | FLOAT (precision ,scale ) UNSIGNED |
double | 双精度 | precision 、scale | DOUBLE (precision ,scale ) |
unsignedDouble | 无符号双精度 | precision 、scale | DOUBLE (precision ,scale ) UNSIGNED |
boolean | 布尔型 | BOOLEAN | |
enum | 枚举型 | option | ENUM(option... ) |
json | JSON 文本 | JSON | |
JSON | JSON 文本(同 json) | JSON | |
jsonb | JSON (二进制格式存储) | JSON | |
JSONB | JSON (二进制格式存储 同 jsonb) | JSON | |
uuid | UUID 格式字符串 | VARCHAR(36) | |
ipAddress | IP 地址 | INT | |
macAddress | MAC 地址 | BIGINT | |
year | 年份 | SMALLINT |
一个字段可以包含多条校验规则,每条校验规则可以选用 min
,max
, pattern
, typeof
等校验方法。
{"columns": [{"label": "手机号","name": "mobile","type": "string","length": 50,"comment": "手机号","index": true,"crypt": "AES","validations": [{"method": "typeof","args": ["string"],"message": "{{input}}类型错误, {{label}}应该为字符串"},{"method": "pattern","args": ["^1[3-9]\\d{9}$"],"message": "{{input}}格式错误"}]}]}
校验规则定义
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
method | String | 校验方法名称,可选值 typeof , pattern 等 | 是 |
args | Array\<String|Integer|Float> | 校验方法参数,例如 [20] , ["^1[3-9]\\d{9}$"] | 否 |
message | String | 如校验不通过,返回的错误提示。支持使用 {{<name>}} 引用字段信息, 如{{label}} 将被替换为字段 label 中定义的数值; {{input}} 被替换为用户输入数值。 | 否 |
校验方法 | 参数 | 说明 | 示例 |
---|---|---|---|
typeof | [<String>] 许可值 string , integer , float , number , datetime , timestamp | 数值类型 | {"method":"typeof", "args":["integer"]} |
min | [<Integer\|Float>] | 最小值 | {"method":"min", "args":[20]} |
max | [<Integer\|Float>] | 最大值 | {"method":"max", "args":[0.618]} |
enum | [String...] | 枚举选项 | {"method":"enum", "args":["enabled", "disabled"]} |
pattern | [String] | 正则匹配 | {"method":"pattern", "args":["^1[3-9]\\d{9}$"]} |
minLength | [<Integer>] | 最小长度 | {"method":"minLength", "args":[20]} |
maxLength | [<Integer>] | 最大长度 | {"method":"maxLength", "args":[100]} |
[] | 邮箱 | {"method":"email", "args":[]} | |
mobile | [<String>] 区域列表(可选), 默认为 cn 许可值 cn ,us | 手机号 | {"method":"mobile", "args":[]} {"method":"mobile", "args":["us"]} |
当前支持 AES
和 PASSWORD
两种字段数值加密存储算法,其中 AES
仅支持 MySQL 数据库。
加密算法 | 说明 | 是否可逆 |
---|---|---|
AES | AES 加密,需设定 XIANG_DB_AESKEY | 是 |
PASSWORD | PASSWORD HASH 加密 | 否 |
以下名称不能用于字段名称。
保留字 | 说明 |
---|---|
created_at | 用于记录创建时间戳 |
updated_at | 用于记录更新时间戳 |
deleted_at | 用于记录软删除标记 |
__restore_data | 用于软删除时备份唯一字段数值 |
indexes
一个数据模型,可以包含多个索引。对于单一索引,推荐在字段定义时,使用 index
、 unique
和 primary
修饰符定义,对于复合索引或全文检索索引,在 indexes
中定义。
{"indexes": [{"comment": "厂商用户","name": "manu_id_mobile_unique","columns": ["manu_id", "mobile"],"type": "unique"},{"comment": "简历全文检索","name": "resume_fulltext","columns": ["resume"],"type": "fulltext"}]}
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 索引名称。命名规范为 字段 1_字段 2_字段 n_索引类型 | 是 |
type | String | 索引类型 许可值 index 索引, unique 唯一索引, primary 主键, fulltext 全文检索 | 是 |
columns | Array\<String> | 关联字段名称列表(顺序有关) ["字段 1","字段 2"] 与 ["字段 2","字段 1"] 不同 | 是 |
comment | String | 索引注释 | 否 |
relations
数据模型支持一对一、一对多两种关系映射,可以通过定义映射关系将多个数据模型关联,查询时使用with
参数即可同时返回关联模型数据。
映射关系名称 | 关系 | 说明 |
---|---|---|
hasOne | 一对一 | 模型 A 与模型 B 通过一对一关联 |
hasMany | 一对多 | 模型 A 与模型 B 通过一对多关联 |
关联关系使用 [key:String]:Object Relation
数据结构定义 ( {"关联名称1":{}, "关联名称2":{}}
, 关联名称为 小写英文字母 )
在模型文件 user.yao
中定义
Object Relation
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
type | String | 关系类型 许可值 hasOne , hasOneThrough , hasMany , hasManyThrough | 是 |
key | String | 关联模型的关联字段名称 | 否 |
model | String | 关联模型名称 | 否 |
foreign | String | 当前模型的关联字段名称 | 否 |
query | Object QueryParam | 关系查询参数默认值。如在查询时未指定关联查询参数,则替使用在模型中定义的查询参数 | 否 |
links | Array\<Object Relation> | hasOneThrough 或 hasManyThrough 多表关联关系定义 | 否 |
hasOne
一对一数据模型 user
数据表结构如下:
字段 | 类型 | 说明 |
---|---|---|
id | ID | 用户 ID |
manu_id | bigInteger | 所属厂商 ID |
name | string | 姓名 |
数据模型 manu
数据表结构如下:
字段 | 类型 | 说明 |
---|---|---|
id | ID | 厂商 ID |
short | string | 厂商简称 |
company | string | 公司名称 |
在查询用户数据时,可以同时列出厂商信息或可以按关联厂商进行查询,则可以在定义 user
数据模型时,设定与 manu
数据模型关系.
在模型文件 user.yao
中定义
{"name": "用户","relations": {"manu": {"type": "hasOne","model": "manu","key": "id","foreign": "manu_id","query": { "select": ["short", "company"] }}}}
说明
1.将关系映射类型指定为 hasOne
2.将关联模型 model
设置为 manu
3.将关联模型 key
设置为 id
, 即:manu.id
引擎处理时,自动关联 manu
表的 id
字段。
4.将 foreign
设置为 manu_id
, 即: user.manu_id
引擎处理时,将 manu.id
和 user.manu_id
关联
5.可以在 query
字段中,设置默认的查询条件,如指定读取的字段等。
引擎解析后的 SQL 为:
SELECT `user`.*,`manu`.`short` AS `user_manu_short`,`manu`.`company` AS `user_manu_company`,FROM `user` AS `user`LEFT JOIN `manu` as `user_manu` ON `user_manu`.`id` = `user`.`manu_id`
访问
在调用 process
查询时,传入 with
参数,即可同时返回厂商信息
GET /api/user/find/1?with=manu&manu.select=id,short
hasMany
一对多数据模型 user
数据表结构如下:
字段 | 类型 | 说明 |
---|---|---|
id | ID | 用户 ID |
manu_id | bigInteger | 所属厂商 ID |
name | string | 姓名 |
数据模型 address
数据表结构如下:
字段 | 类型 | 说明 |
---|---|---|
id | ID | 地址 ID |
user_id | bigInteger | 所属用户 ID (关联 user.id ) |
location | string | 详细地址 |
对于类似一个用户有多个通信地址的业务场景,可以通过建立一对多的映射关系来实现。
在模型文件 user.yao
中定义
{"name": "用户","relations": {"addresses": {"type": "hasMany","model": "address","key": "user_id","foreign": "id","query": {"select": ["location"],"limit": 20}}}}
说明
1.将关系映射类型指定为 hasMany
2.将关联模型 model
设置为 address
3.将关联模型 key
设置为 user_id
, 即:address.user_id
引擎处理时,自动关联 address
表的 user_id
字段。
4.将 foreign
设置为 id
, 即: user.id
引擎处理时,将 user.id
和 address.user_id
关联
5.可以在 query
字段中,设置默认的查询条件,如指定读取的字段等。对于 hasMany
建议设置默认 limit
约束返回数据条目
对于 hasMany
类型关系映射,引擎将分两次查询。首次查询出主模型以及关联的 ID 列表,第二次根据 ID 列表,查询关联数据信息。
第一次查询:
SELECT `user`.* FROM `user` AS `user`
引擎处理结果,并读取 user
.id
第二次查询:
SELECT `address`.`user_id`, `address`.`location` FROM `address` AS `address`WHERE `address`.`user_id` IN (<user.id...>)
引擎处理结果,关联用户地址信息
访问
在调用 process
查询时,传入 with
参数,即可同时取得 addresses
的关联信息
GET /api/user/find/1?with=addresses
option
在 option
中设定模型配置参数
{"name": "地址","option": {"timestamps": true,"soft_deletes": true}}
选项 | 类型 | 说明 |
---|---|---|
timestamps | Bool | 为 true 时, 自动创建 created_at 、updated_at 字段,并在插入和更新数据时,标记对应操作时间 |
soft_deletes | Bool | 为 true 时, 自动创建 deleted_at 和 __restore_data 字段,数据删除时,备份唯一字段数据,并标记操作时间,查询时忽略已标记删除的数据 |
QueryParam
在模型关联关系定义和调用处理器时,通过 Object QueryParam
描述查询条件。
{"select": ["id", "name", "mobile", "status"],"withs": {"manu": {"query": {"select": ["name", "short_name", "status"]}},"addresses": {}},"wheres": [{ "column": "status", "value": "enabled" },{ "rel": "manu", "column": "status", "value": "enabled" },{"wheres": [{ "column": "name", "value": "%张三%", "op": "like" },{"method": "orwhere","column": "name","value": "%李四%","op": "like"}]}],"orders": [{ "column": "id", "option": "desc" },{ "rel": "manu", "column": "name" }],"limit": 2}
应用引擎将以上查询条件解析为如下 SQL :
SELECT`user`.`id`,`user`.`name`,`user`.`mobile`,`user`.`status`,`user_manu`.`name` AS `user_manu_name`,`user_manu`.`short_name` AS `user_manu_short_name` ,`user_manu`.`status` AS `user_manu_status`FROM `user` AS `user`LEFT JOIN `manu` AS `user_manu` ON `user_manu`.`id` = `user`.`manu_id`WHERE `user`.`status` = 'enabled'AND `user_manu`.`status` = 'enabled'AND (`user`.`name` like '%张三%' OR `user`.`name` like '%李四%')ORDER BY `user`.`id` desc, `user_manu`.`name` ascLIMIT 2
QueryParam
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
select | Array\<String> | 选择字段清单 | 否 |
wheres | Array\<Object Where> | 查询条件 | 否 |
orders | Array\<Object Order> | 排序条件 | 否 |
limit | Integer | 返回记录条目 | 否 |
page | Integer | 当前页码 | 否 |
pagesize | Integer | 每页显示记录数量 | 否 |
withs | [key:String]:Object With | 读取关联模型 | 否 |
Object Where
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
rel | String | 如按关联模型的字段查询,则填写关联模型名称 | 否 |
column | String | 字段名称 | 否 |
method | String | 查询方法 where ,orwhere | 否 |
op | String | 匹配关系 eq ,like ,in ,gt 等 | 否 |
value | Any | 匹配数值 | 否 |
wheres | Array\<Object Where> | 分组查询 | 否 |
查询方法 | 说明 |
---|---|
where | WHERE 字段 = 数值, WHERE 字段 >= 数值 |
orwhere | ... OR WHERE 字段 = 数值 |
匹配关系 | 说明 |
---|---|
eq | 默认值 等于 WHERE 字段 = 数值 |
like | 匹配 WHERE 字段 like 数值 |
gt | 大于 WHERE 字段 > 数值 |
ge | 大于等于 WHERE 字段 >= 数值 |
lt | 小于 WHERE 字段 < 数值 |
le | 小于等于 WHERE 字段 <= 数值 |
null | 为空 WHERE 字段 IS NULL |
notnull | 不为空 WHERE 字段 IS NOT NULL |
in | 列表包含 WHERE 字段 IN (数值...) |
Object Order
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
rel | String | 如按关联模型的字段排序,则填写关联模型名称 | 否 |
column | String | 字段名称 | 否 |
option | String | 排序方式,默认为 asc desc, asc | 否 |
Object With
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 关联关系名称 | 否 |
query | Object QueryParam | 查询参数 | 否 |
查看 代码示例
Yao 可以读取数据模型定义,实现数据迁移、元数据原子操作、元数据输入校验和元数据管理后台。元数据原子操作方法被映射为处理器(process
),支持模型间数据关系映射,可在数据流(Flow
)和接口(API
)中访问查询。如采用golang
语言开发业务插件(Plugin
),可以使用 Package Gou
访问模型的各个方法, 后续将提供 NodeJS
等语言 SDK。一个数据模型对应数据库中的一张数据表, 通过 JSON 文件描述数据表结构,放置在models
目录中。使用 yao migrate
命令创建/更新数据表结构设计。
处理器 | 说明 | 文档 |
---|---|---|
models.<模型名称>.Find | 查询单条记录 | 查看 |
models.<模型名称>.Get | 按条件查询, 不分页 | 查看 |
models.<模型名称>.Paginate | 按条件查询, 分页 | 查看 |
models.<模型名称>.Create | 创建单条记录, 返回新创建记录 ID | 查看 |
models.<模型名称>.Update | 更新单条记录 | 查看 |
models.<模型名称>.Save | 保存单条记录, 不存在创建记录, 存在更新记录, 返回记录 ID | 查看 |
models.<模型名称>.Delete | 删除单条记录(标记删除) | 查看 |
models.<模型名称>.Destroy | 删除单条记录(真删除) | 查看 |
models.<模型名称>.Insert | 插入多条记录, 返回插入行数 | 查看 |
models.<模型名称>.UpdateWhere | 按条件更新记录, 返回更新行数 | 查看 |
models.<模型名称>.DeleteWhere | 按条件删除数据, 返回删除行数(标记删除) | 查看 |
models.<模型名称>.DestroyWhere | 按条件删除数据, 返回删除行数(真删除) | 查看 |
models.<模型名称>.EachSave | 保存多条记录, 不存在创建记录, 存在更新记录, 返回记录 ID 集合 | 查看 |
models.<模型名称>.EachSaveAfterDelete | 删除一组给定 ID 的记录后,保存多条记录, 不存在创建, 存在更新, 返回 ID 集合 | 查看 |
数据模型描述文件是以 小写英文字母 命名的 JSON 文本文件 <name>.mod.yao
文件夹 (相对应用模型根目录) | 文件名 | 模型名称 | Process (在 API /Flow 中引用) |
---|---|---|---|
/ | name.mod.yao | name | models.name.<process> |
/group/ | name.mod.yao | gorup.name | models.gorup.name.<process> |
/group1/group2/ | name.mod.yao | gorup1.gorup2.name | models.gorup1.group2.name.<process> |
{"name": "用户","table": {},"columns": [],"indexes": [],"relations": {},"values": [],"option": {}}
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 模型中文名称 | 是 |
table | Object | 数据表定义 | 是 |
columns | Array\<Object> | 字段定义 | 是 |
indexes | Array\<Object> | 索引定义 | 是 |
relations | [key:String]:Object | 关系映射 | 否 |
values | Array\<Object> | 默认数据 | 否 |
option | Object | 配置选型 | 否 |
数据表格包含 name
、comment
等字段,定义模型存储在数据库中的数据表名称、注释等信息。支持 MySQL
, PostgreSQL
、SQLite
等 Xun Database
或第三方提供驱动的数据库。
{"table": {"name": "user","comment": "用户表","engine": "InnoDB"}}
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 数据表名称 | 是 |
comment | String | 数据表注释中文名 | 否 |
engine | String | 数据表引擎(MySQL ONLY) 许可值 InnoDB , MyISAM | 否 |
columns
一个模型可以包含多个字段定义,每个字段定义包含 label
、name
、type
、 validations
等信息。
{"columns": [{ "label": "ID", "name": "id", "type": "ID" },{"label": "厂商","name": "manu_id","type": "bigInteger","length": 50,"comment": "所属厂商","nullable": true,"index": true,"validations": [{"method": "typeof","args": ["integer"],"message": "{{input}}类型错误, {{label}}应为数字"},{"method": "min","args": [0],"message": "{{label}}应大于0"}]},{"label": "手机号","name": "mobile","type": "string","length": 50,"comment": "手机号","index": true,"crypt": "AES","validations": [{"method": "typeof","args": ["string"],"message": "{{input}}类型错误, {{label}}应该为字符串"},{"method": "pattern","args": ["^1[3-9]\\d{9}$"],"message": "{{input}}格式错误"}]}]}
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 字段名称,对应数据表中字段名称 | 是 |
type | String | 字段类型, | 是 |
label | String | 字段显示名称,用于在管理表单,开发平台等成场景下呈现 | 是 |
comment | String | 字段注释,对应数据表中字段注释 | 否 |
title | String | 字段标题,可用于开发平台中呈现 | 否 |
description | String | 字段介绍,可用于开发平台中呈现 | 否 |
length | Integer | 字段长度,对 string 等类型字段有效 | 否 |
precision | Integer | 字段位数(含小数位),对 float 、decimal 等类型字段有效 | 否 |
scale | Integer | 字段小数位位数,对 float 、decimal 等类型字段有效 | 否 |
option | Array\<String> | 字段许可值,对 enum 类型字段有效 | 否 |
default | String|Integer|Float | 字段默认值 | 否 |
default_raw | String | 字段默认值,支持数据库函数,如 NOW() default 和 default_raw 同时存在 default_raw 优先级高 | 否 |
crypt | String | 字段加密存储方式(MySQL Only)。许可值 AES , PASSWORD | 否 |
nullable | Bool | 字段是否可以为空,默认为 false | 否 |
index | Bool | 字段是否为索引,默认为 false | 否 |
unique | Bool | 字段是否为唯一索引,默认为 false , 如为 true 无需同时将 index 设置为 true | 否 |
primary | Bool | 字段是否为主键,每张表至多一个主键字段。默认为 false | 否 |
validations | Array\<Object> | 字段校验规则 | 否 |
类型 | 说明 | 可选参数 | MySQL 字段类型 |
---|---|---|---|
string | 字符串 | length | VARCHAR(length ) |
char | 字符 | length | CHAR (length ) |
text | 文本 | TEXT | |
mediumText | 中文本 | MEDIUMTEXT | |
longText | 长文本 | LONGTEXT | |
binary | 二进制数据 | VARBINARY | |
date | 日期 | DATE | |
datetime | 日期时间 | length | DATETIME |
datetimeTz | 带时区的日期时间 | length | DATETIME |
time | 时间 | length | TIME |
timeTz | 带时区的时间 | length | TIME |
timestamp | 时间戳 | length | TIMESTAMP |
timestampTz | 带时区的时间戳 | length | TIMESTAMP |
tinyInteger | 微整型 | TINYINT | |
tinyIncrements | 无符号微整型+自增 | TINYINT UNSIGNED AUTO_INCREMENT | |
unsignedTinyInteger | 无符号微整型 | TINYINT UNSIGNED | |
smallInteger | 小整型 | SMALLINT | |
smallIncrements | 无符号小整型+自增 | SMALLINT UNSIGNED AUTO_INCREMENT | |
unsignedSmallInteger | 无符号小整型 | SMALLINT UNSIGNED | |
integer | 整型 | INT | |
increments | 无符号整型+自增 | INT UNSIGNED AUTO_INCREMENT | |
unsignedInteger | 无符号整型 | INT UNSIGNED | |
bigInteger | 长整型 | BIGINT | |
bigIncrements | 无符号长整型+自增 | BIGINT UNSIGNED AUTO_INCREMENT | |
unsignedBigInteger | 无符号长整型 | BIGINT UNSIGNED | |
id | 长整型+自增 | BIGINT UNSIGNED AUTO_INCREMENT | |
ID | 长整型+自增(同 id) | BIGINT UNSIGNED AUTO_INCREMENT | |
decimal | 小数(一般用于存储货币) | precision 、scale | DECIMAL(precision ,scale ) |
unsignedDecimal | 无符号小数 (一般用于存储货币) | precision 、scale | DECIMAL (precision ,scale ) UNSIGNED |
float | 浮点数 | precision 、scale | FLOAT (precision ,scale ) |
unsignedFloat | 无符号浮点数 | precision 、scale | FLOAT (precision ,scale ) UNSIGNED |
double | 双精度 | precision 、scale | DOUBLE (precision ,scale ) |
unsignedDouble | 无符号双精度 | precision 、scale | DOUBLE (precision ,scale ) UNSIGNED |
boolean | 布尔型 | BOOLEAN | |
enum | 枚举型 | option | ENUM(option... ) |
json | JSON 文本 | JSON | |
JSON | JSON 文本(同 json) | JSON | |
jsonb | JSON (二进制格式存储) | JSON | |
JSONB | JSON (二进制格式存储 同 jsonb) | JSON | |
uuid | UUID 格式字符串 | VARCHAR(36) | |
ipAddress | IP 地址 | INT | |
macAddress | MAC 地址 | BIGINT | |
year | 年份 | SMALLINT |
一个字段可以包含多条校验规则,每条校验规则可以选用 min
,max
, pattern
, typeof
等校验方法。
{"columns": [{"label": "手机号","name": "mobile","type": "string","length": 50,"comment": "手机号","index": true,"crypt": "AES","validations": [{"method": "typeof","args": ["string"],"message": "{{input}}类型错误, {{label}}应该为字符串"},{"method": "pattern","args": ["^1[3-9]\\d{9}$"],"message": "{{input}}格式错误"}]}]}
校验规则定义
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
method | String | 校验方法名称,可选值 typeof , pattern 等 | 是 |
args | Array\<String|Integer|Float> | 校验方法参数,例如 [20] , ["^1[3-9]\\d{9}$"] | 否 |
message | String | 如校验不通过,返回的错误提示。支持使用 {{<name>}} 引用字段信息, 如{{label}} 将被替换为字段 label 中定义的数值; {{input}} 被替换为用户输入数值。 | 否 |
校验方法 | 参数 | 说明 | 示例 |
---|---|---|---|
typeof | [<String>] 许可值 string , integer , float , number , datetime , timestamp | 数值类型 | {"method":"typeof", "args":["integer"]} |
min | [<Integer\|Float>] | 最小值 | {"method":"min", "args":[20]} |
max | [<Integer\|Float>] | 最大值 | {"method":"max", "args":[0.618]} |
enum | [String...] | 枚举选项 | {"method":"enum", "args":["enabled", "disabled"]} |
pattern | [String] | 正则匹配 | {"method":"pattern", "args":["^1[3-9]\\d{9}$"]} |
minLength | [<Integer>] | 最小长度 | {"method":"minLength", "args":[20]} |
maxLength | [<Integer>] | 最大长度 | {"method":"maxLength", "args":[100]} |
[] | 邮箱 | {"method":"email", "args":[]} | |
mobile | [<String>] 区域列表(可选), 默认为 cn 许可值 cn ,us | 手机号 | {"method":"mobile", "args":[]} {"method":"mobile", "args":["us"]} |
当前支持 AES
和 PASSWORD
两种字段数值加密存储算法,其中 AES
仅支持 MySQL 数据库。
加密算法 | 说明 | 是否可逆 |
---|---|---|
AES | AES 加密,需设定 XIANG_DB_AESKEY | 是 |
PASSWORD | PASSWORD HASH 加密 | 否 |
以下名称不能用于字段名称。
保留字 | 说明 |
---|---|
created_at | 用于记录创建时间戳 |
updated_at | 用于记录更新时间戳 |
deleted_at | 用于记录软删除标记 |
__restore_data | 用于软删除时备份唯一字段数值 |
indexes
一个数据模型,可以包含多个索引。对于单一索引,推荐在字段定义时,使用 index
、 unique
和 primary
修饰符定义,对于复合索引或全文检索索引,在 indexes
中定义。
{"indexes": [{"comment": "厂商用户","name": "manu_id_mobile_unique","columns": ["manu_id", "mobile"],"type": "unique"},{"comment": "简历全文检索","name": "resume_fulltext","columns": ["resume"],"type": "fulltext"}]}
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 索引名称。命名规范为 字段 1_字段 2_字段 n_索引类型 | 是 |
type | String | 索引类型 许可值 index 索引, unique 唯一索引, primary 主键, fulltext 全文检索 | 是 |
columns | Array\<String> | 关联字段名称列表(顺序有关) ["字段 1","字段 2"] 与 ["字段 2","字段 1"] 不同 | 是 |
comment | String | 索引注释 | 否 |
relations
数据模型支持一对一、一对多两种关系映射,可以通过定义映射关系将多个数据模型关联,查询时使用with
参数即可同时返回关联模型数据。
映射关系名称 | 关系 | 说明 |
---|---|---|
hasOne | 一对一 | 模型 A 与模型 B 通过一对一关联 |
hasMany | 一对多 | 模型 A 与模型 B 通过一对多关联 |
关联关系使用 [key:String]:Object Relation
数据结构定义 ( {"关联名称1":{}, "关联名称2":{}}
, 关联名称为 小写英文字母 )
在模型文件 user.yao
中定义
Object Relation
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
type | String | 关系类型 许可值 hasOne , hasOneThrough , hasMany , hasManyThrough | 是 |
key | String | 关联模型的关联字段名称 | 否 |
model | String | 关联模型名称 | 否 |
foreign | String | 当前模型的关联字段名称 | 否 |
query | Object QueryParam | 关系查询参数默认值。如在查询时未指定关联查询参数,则替使用在模型中定义的查询参数 | 否 |
links | Array\<Object Relation> | hasOneThrough 或 hasManyThrough 多表关联关系定义 | 否 |
hasOne
一对一数据模型 user
数据表结构如下:
字段 | 类型 | 说明 |
---|---|---|
id | ID | 用户 ID |
manu_id | bigInteger | 所属厂商 ID |
name | string | 姓名 |
数据模型 manu
数据表结构如下:
字段 | 类型 | 说明 |
---|---|---|
id | ID | 厂商 ID |
short | string | 厂商简称 |
company | string | 公司名称 |
在查询用户数据时,可以同时列出厂商信息或可以按关联厂商进行查询,则可以在定义 user
数据模型时,设定与 manu
数据模型关系.
在模型文件 user.yao
中定义
{"name": "用户","relations": {"manu": {"type": "hasOne","model": "manu","key": "id","foreign": "manu_id","query": { "select": ["short", "company"] }}}}
说明
1.将关系映射类型指定为 hasOne
2.将关联模型 model
设置为 manu
3.将关联模型 key
设置为 id
, 即:manu.id
引擎处理时,自动关联 manu
表的 id
字段。
4.将 foreign
设置为 manu_id
, 即: user.manu_id
引擎处理时,将 manu.id
和 user.manu_id
关联
5.可以在 query
字段中,设置默认的查询条件,如指定读取的字段等。
引擎解析后的 SQL 为:
SELECT `user`.*,`manu`.`short` AS `user_manu_short`,`manu`.`company` AS `user_manu_company`,FROM `user` AS `user`LEFT JOIN `manu` as `user_manu` ON `user_manu`.`id` = `user`.`manu_id`
访问
在调用 process
查询时,传入 with
参数,即可同时返回厂商信息
GET /api/user/find/1?with=manu&manu.select=id,short
hasMany
一对多数据模型 user
数据表结构如下:
字段 | 类型 | 说明 |
---|---|---|
id | ID | 用户 ID |
manu_id | bigInteger | 所属厂商 ID |
name | string | 姓名 |
数据模型 address
数据表结构如下:
字段 | 类型 | 说明 |
---|---|---|
id | ID | 地址 ID |
user_id | bigInteger | 所属用户 ID (关联 user.id ) |
location | string | 详细地址 |
对于类似一个用户有多个通信地址的业务场景,可以通过建立一对多的映射关系来实现。
在模型文件 user.yao
中定义
{"name": "用户","relations": {"addresses": {"type": "hasMany","model": "address","key": "user_id","foreign": "id","query": {"select": ["location"],"limit": 20}}}}
说明
1.将关系映射类型指定为 hasMany
2.将关联模型 model
设置为 address
3.将关联模型 key
设置为 user_id
, 即:address.user_id
引擎处理时,自动关联 address
表的 user_id
字段。
4.将 foreign
设置为 id
, 即: user.id
引擎处理时,将 user.id
和 address.user_id
关联
5.可以在 query
字段中,设置默认的查询条件,如指定读取的字段等。对于 hasMany
建议设置默认 limit
约束返回数据条目
对于 hasMany
类型关系映射,引擎将分两次查询。首次查询出主模型以及关联的 ID 列表,第二次根据 ID 列表,查询关联数据信息。
第一次查询:
SELECT `user`.* FROM `user` AS `user`
引擎处理结果,并读取 user
.id
第二次查询:
SELECT `address`.`user_id`, `address`.`location` FROM `address` AS `address`WHERE `address`.`user_id` IN (<user.id...>)
引擎处理结果,关联用户地址信息
访问
在调用 process
查询时,传入 with
参数,即可同时取得 addresses
的关联信息
GET /api/user/find/1?with=addresses
option
在 option
中设定模型配置参数
{"name": "地址","option": {"timestamps": true,"soft_deletes": true}}
选项 | 类型 | 说明 |
---|---|---|
timestamps | Bool | 为 true 时, 自动创建 created_at 、updated_at 字段,并在插入和更新数据时,标记对应操作时间 |
soft_deletes | Bool | 为 true 时, 自动创建 deleted_at 和 __restore_data 字段,数据删除时,备份唯一字段数据,并标记操作时间,查询时忽略已标记删除的数据 |
QueryParam
在模型关联关系定义和调用处理器时,通过 Object QueryParam
描述查询条件。
{"select": ["id", "name", "mobile", "status"],"withs": {"manu": {"query": {"select": ["name", "short_name", "status"]}},"addresses": {}},"wheres": [{ "column": "status", "value": "enabled" },{ "rel": "manu", "column": "status", "value": "enabled" },{"wheres": [{ "column": "name", "value": "%张三%", "op": "like" },{"method": "orwhere","column": "name","value": "%李四%","op": "like"}]}],"orders": [{ "column": "id", "option": "desc" },{ "rel": "manu", "column": "name" }],"limit": 2}
应用引擎将以上查询条件解析为如下 SQL :
SELECT`user`.`id`,`user`.`name`,`user`.`mobile`,`user`.`status`,`user_manu`.`name` AS `user_manu_name`,`user_manu`.`short_name` AS `user_manu_short_name` ,`user_manu`.`status` AS `user_manu_status`FROM `user` AS `user`LEFT JOIN `manu` AS `user_manu` ON `user_manu`.`id` = `user`.`manu_id`WHERE `user`.`status` = 'enabled'AND `user_manu`.`status` = 'enabled'AND (`user`.`name` like '%张三%' OR `user`.`name` like '%李四%')ORDER BY `user`.`id` desc, `user_manu`.`name` ascLIMIT 2
QueryParam
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
select | Array\<String> | 选择字段清单 | 否 |
wheres | Array\<Object Where> | 查询条件 | 否 |
orders | Array\<Object Order> | 排序条件 | 否 |
limit | Integer | 返回记录条目 | 否 |
page | Integer | 当前页码 | 否 |
pagesize | Integer | 每页显示记录数量 | 否 |
withs | [key:String]:Object With | 读取关联模型 | 否 |
Object Where
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
rel | String | 如按关联模型的字段查询,则填写关联模型名称 | 否 |
column | String | 字段名称 | 否 |
method | String | 查询方法 where ,orwhere | 否 |
op | String | 匹配关系 eq ,like ,in ,gt 等 | 否 |
value | Any | 匹配数值 | 否 |
wheres | Array\<Object Where> | 分组查询 | 否 |
查询方法 | 说明 |
---|---|
where | WHERE 字段 = 数值, WHERE 字段 >= 数值 |
orwhere | ... OR WHERE 字段 = 数值 |
匹配关系 | 说明 |
---|---|
eq | 默认值 等于 WHERE 字段 = 数值 |
like | 匹配 WHERE 字段 like 数值 |
gt | 大于 WHERE 字段 > 数值 |
ge | 大于等于 WHERE 字段 >= 数值 |
lt | 小于 WHERE 字段 < 数值 |
le | 小于等于 WHERE 字段 <= 数值 |
null | 为空 WHERE 字段 IS NULL |
notnull | 不为空 WHERE 字段 IS NOT NULL |
in | 列表包含 WHERE 字段 IN (数值...) |
Object Order
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
rel | String | 如按关联模型的字段排序,则填写关联模型名称 | 否 |
column | String | 字段名称 | 否 |
option | String | 排序方式,默认为 asc desc, asc | 否 |
Object With
字段 | 类型 | 说明 | 必填项 |
---|---|---|---|
name | String | 关联关系名称 | 否 |
query | Object QueryParam | 查询参数 | 否 |