数据模型

查看源码

查看 代码示例

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.yaonamemodels.name.<process>
/group/name.mod.yaogorup.namemodels.gorup.name.<process>
/group1/group2/name.mod.yaogorup1.gorup2.namemodels.gorup1.group2.name.<process>

文档结构

{
"name": "用户",
"table": {},
"columns": [],
"indexes": [],
"relations": {},
"values": [],
"option": {}
}
字段类型说明必填项
nameString模型中文名称
tableObject数据表定义
columnsArray\<Object>字段定义
indexesArray\<Object>索引定义
relations[key:String]:Object关系映射
valuesArray\<Object>默认数据
optionObject配置选型

数据表格包含 namecomment 等字段,定义模型存储在数据库中的数据表名称、注释等信息。支持 MySQL, PostgreSQLSQLiteXun Database 或第三方提供驱动的数据库。

{
"table": {
"name": "user",
"comment": "用户表",
"engine": "InnoDB"
}
}
字段类型说明必填项
nameString数据表名称
commentString数据表注释中文名
engineString数据表引擎(MySQL ONLY) 许可值 InnoDB, MyISAM

2.3 字段定义 columns

一个模型可以包含多个字段定义,每个字段定义包含 labelnametypevalidations 等信息。

{
"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}}格式错误"
}
]
}
]
}
字段类型说明必填项
nameString字段名称,对应数据表中字段名称
typeString字段类型,
labelString字段显示名称,用于在管理表单,开发平台等成场景下呈现
commentString字段注释,对应数据表中字段注释
titleString字段标题,可用于开发平台中呈现
descriptionString字段介绍,可用于开发平台中呈现
lengthInteger字段长度,对 string 等类型字段有效
precisionInteger字段位数(含小数位),对 floatdecimal 等类型字段有效
scaleInteger字段小数位位数,对 floatdecimal 等类型字段有效
optionArray\<String>字段许可值,对 enum 类型字段有效
defaultString|Integer|Float字段默认值
default_rawString字段默认值,支持数据库函数,如 NOW() default 和 default_raw 同时存在 default_raw 优先级高
cryptString字段加密存储方式(MySQL Only)。许可值 AES, PASSWORD
nullableBool字段是否可以为空,默认为 false
indexBool字段是否为索引,默认为 false
uniqueBool字段是否为唯一索引,默认为 false , 如为 true 无需同时将 index 设置为 true
primaryBool字段是否为主键,每张表至多一个主键字段。默认为 false
validationsArray\<Object>字段校验规则

字段类型

类型说明可选参数MySQL 字段类型
string字符串lengthVARCHAR(length )
char字符lengthCHAR (length )
text文本TEXT
mediumText中文本MEDIUMTEXT
longText长文本LONGTEXT
binary二进制数据VARBINARY
date日期DATE
datetime日期时间lengthDATETIME
datetimeTz带时区的日期时间lengthDATETIME
time时间lengthTIME
timeTz带时区的时间lengthTIME
timestamp时间戳lengthTIMESTAMP
timestampTz带时区的时间戳lengthTIMESTAMP
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小数(一般用于存储货币)precisionscaleDECIMAL(precision,scale)
unsignedDecimal无符号小数 (一般用于存储货币)precisionscaleDECIMAL (precision,scale) UNSIGNED
float浮点数precisionscaleFLOAT (precision,scale)
unsignedFloat无符号浮点数precisionscaleFLOAT (precision,scale) UNSIGNED
double双精度precisionscaleDOUBLE (precision,scale)
unsignedDouble无符号双精度precisionscaleDOUBLE (precision,scale) UNSIGNED
boolean布尔型BOOLEAN
enum枚举型optionENUM(option...)
jsonJSON 文本JSON
JSONJSON 文本(同 json)JSON
jsonbJSON (二进制格式存储)JSON
JSONBJSON (二进制格式存储 同 jsonb)JSON
uuidUUID 格式字符串VARCHAR(36)
ipAddressIP 地址INT
macAddressMAC 地址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}}格式错误"
}
]
}
]
}

校验规则定义

字段类型说明必填项
methodString校验方法名称,可选值 typeof, pattern
argsArray\<String|Integer|Float>校验方法参数,例如 [20], ["^1[3-9]\\d{9}$"]
messageString如校验不通过,返回的错误提示。支持使用 {{<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]}
email[]邮箱{"method":"email", "args":[]}
mobile[<String>] 区域列表(可选), 默认为 cn 许可值 cn,us手机号{"method":"mobile", "args":[]} {"method":"mobile", "args":["us"]}

加密方式

当前支持 AESPASSWORD 两种字段数值加密存储算法,其中 AES 仅支持 MySQL 数据库。

加密算法说明是否可逆
AESAES 加密,需设定 XIANG_DB_AESKEY
PASSWORDPASSWORD HASH 加密

保留字

以下名称不能用于字段名称。

保留字说明
created_at用于记录创建时间戳
updated_at用于记录更新时间戳
deleted_at用于记录软删除标记
__restore_data用于软删除时备份唯一字段数值

索引定义 indexes

一个数据模型,可以包含多个索引。对于单一索引,推荐在字段定义时,使用 indexuniqueprimary 修饰符定义,对于复合索引或全文检索索引,在 indexes 中定义。

{
"indexes": [
{
"comment": "厂商用户",
"name": "manu_id_mobile_unique",
"columns": ["manu_id", "mobile"],
"type": "unique"
},
{
"comment": "简历全文检索",
"name": "resume_fulltext",
"columns": ["resume"],
"type": "fulltext"
}
]
}
字段类型说明必填项
nameString索引名称。命名规范为 字段 1_字段 2_字段 n_索引类型
typeString索引类型 许可值 index 索引, unique 唯一索引, primary 主键, fulltext 全文检索
columnsArray\<String>关联字段名称列表(顺序有关) ["字段 1","字段 2"]["字段 2","字段 1"] 不同
commentString索引注释

关系映射 relations

数据模型支持一对一、一对多两种关系映射,可以通过定义映射关系将多个数据模型关联,查询时使用with参数即可同时返回关联模型数据。

映射关系名称关系说明
hasOne一对一模型 A 与模型 B 通过一对一关联
hasMany一对多模型 A 与模型 B 通过一对多关联

关联关系使用 [key:String]:Object Relation 数据结构定义 ( {"关联名称1":{}, "关联名称2":{}}, 关联名称为 小写英文字母 )

在模型文件 user.yao 中定义

查看源码

Object Relation

字段类型说明必填项
typeString关系类型 许可值 hasOne, hasOneThrough , hasMany , hasManyThrough
keyString关联模型的关联字段名称
modelString关联模型名称
foreignString当前模型的关联字段名称
queryObject QueryParam关系查询参数默认值。如在查询时未指定关联查询参数,则替使用在模型中定义的查询参数
linksArray\<Object Relation>hasOneThroughhasManyThrough 多表关联关系定义

hasOne 一对一

数据模型 user 数据表结构如下:

字段类型说明
idID用户 ID
manu_idbigInteger所属厂商 ID
namestring姓名

数据模型 manu 数据表结构如下:

字段类型说明
idID厂商 ID
shortstring厂商简称
companystring公司名称

在查询用户数据时,可以同时列出厂商信息或可以按关联厂商进行查询,则可以在定义 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.iduser.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 数据表结构如下:

字段类型说明
idID用户 ID
manu_idbigInteger所属厂商 ID
namestring姓名

数据模型 address 数据表结构如下:

字段类型说明
idID地址 ID
user_idbigInteger所属用户 ID (关联 user.id )
locationstring详细地址

对于类似一个用户有多个通信地址的业务场景,可以通过建立一对多的映射关系来实现。

在模型文件 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.idaddress.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
}
}
选项类型说明
timestampsBool为 true 时, 自动创建 created_atupdated_at 字段,并在插入和更新数据时,标记对应操作时间
soft_deletesBool为 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` asc
LIMIT 2

数据结构

QueryParam

字段类型说明必填项
selectArray\<String>选择字段清单
wheresArray\<Object Where>查询条件
ordersArray\<Object Order>排序条件
limitInteger返回记录条目
pageInteger当前页码
pagesizeInteger每页显示记录数量
withs[key:String]:Object With读取关联模型

Object Where

字段类型说明必填项
relString如按关联模型的字段查询,则填写关联模型名称
columnString字段名称
methodString查询方法 where,orwhere
opString匹配关系 eq,like,in,gt
valueAny匹配数值
wheresArray\<Object Where>分组查询
查询方法说明
whereWHERE 字段 = 数值, 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

字段类型说明必填项
relString如按关联模型的字段排序,则填写关联模型名称
columnString字段名称
optionString排序方式,默认为 asc desc, asc

Object With

字段类型说明必填项
nameString关联关系名称
queryObject 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.yaonamemodels.name.<process>
/group/name.mod.yaogorup.namemodels.gorup.name.<process>
/group1/group2/name.mod.yaogorup1.gorup2.namemodels.gorup1.group2.name.<process>

文档结构

{
"name": "用户",
"table": {},
"columns": [],
"indexes": [],
"relations": {},
"values": [],
"option": {}
}
字段类型说明必填项
nameString模型中文名称
tableObject数据表定义
columnsArray\<Object>字段定义
indexesArray\<Object>索引定义
relations[key:String]:Object关系映射
valuesArray\<Object>默认数据
optionObject配置选型

数据表格包含 namecomment 等字段,定义模型存储在数据库中的数据表名称、注释等信息。支持 MySQL, PostgreSQLSQLiteXun Database 或第三方提供驱动的数据库。

{
"table": {
"name": "user",
"comment": "用户表",
"engine": "InnoDB"
}
}
字段类型说明必填项
nameString数据表名称
commentString数据表注释中文名
engineString数据表引擎(MySQL ONLY) 许可值 InnoDB, MyISAM

2.3 字段定义 columns

一个模型可以包含多个字段定义,每个字段定义包含 labelnametypevalidations 等信息。

{
"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}}格式错误"
}
]
}
]
}
字段类型说明必填项
nameString字段名称,对应数据表中字段名称
typeString字段类型,
labelString字段显示名称,用于在管理表单,开发平台等成场景下呈现
commentString字段注释,对应数据表中字段注释
titleString字段标题,可用于开发平台中呈现
descriptionString字段介绍,可用于开发平台中呈现
lengthInteger字段长度,对 string 等类型字段有效
precisionInteger字段位数(含小数位),对 floatdecimal 等类型字段有效
scaleInteger字段小数位位数,对 floatdecimal 等类型字段有效
optionArray\<String>字段许可值,对 enum 类型字段有效
defaultString|Integer|Float字段默认值
default_rawString字段默认值,支持数据库函数,如 NOW() default 和 default_raw 同时存在 default_raw 优先级高
cryptString字段加密存储方式(MySQL Only)。许可值 AES, PASSWORD
nullableBool字段是否可以为空,默认为 false
indexBool字段是否为索引,默认为 false
uniqueBool字段是否为唯一索引,默认为 false , 如为 true 无需同时将 index 设置为 true
primaryBool字段是否为主键,每张表至多一个主键字段。默认为 false
validationsArray\<Object>字段校验规则

字段类型

类型说明可选参数MySQL 字段类型
string字符串lengthVARCHAR(length )
char字符lengthCHAR (length )
text文本TEXT
mediumText中文本MEDIUMTEXT
longText长文本LONGTEXT
binary二进制数据VARBINARY
date日期DATE
datetime日期时间lengthDATETIME
datetimeTz带时区的日期时间lengthDATETIME
time时间lengthTIME
timeTz带时区的时间lengthTIME
timestamp时间戳lengthTIMESTAMP
timestampTz带时区的时间戳lengthTIMESTAMP
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小数(一般用于存储货币)precisionscaleDECIMAL(precision,scale)
unsignedDecimal无符号小数 (一般用于存储货币)precisionscaleDECIMAL (precision,scale) UNSIGNED
float浮点数precisionscaleFLOAT (precision,scale)
unsignedFloat无符号浮点数precisionscaleFLOAT (precision,scale) UNSIGNED
double双精度precisionscaleDOUBLE (precision,scale)
unsignedDouble无符号双精度precisionscaleDOUBLE (precision,scale) UNSIGNED
boolean布尔型BOOLEAN
enum枚举型optionENUM(option...)
jsonJSON 文本JSON
JSONJSON 文本(同 json)JSON
jsonbJSON (二进制格式存储)JSON
JSONBJSON (二进制格式存储 同 jsonb)JSON
uuidUUID 格式字符串VARCHAR(36)
ipAddressIP 地址INT
macAddressMAC 地址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}}格式错误"
}
]
}
]
}

校验规则定义

字段类型说明必填项
methodString校验方法名称,可选值 typeof, pattern
argsArray\<String|Integer|Float>校验方法参数,例如 [20], ["^1[3-9]\\d{9}$"]
messageString如校验不通过,返回的错误提示。支持使用 {{<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]}
email[]邮箱{"method":"email", "args":[]}
mobile[<String>] 区域列表(可选), 默认为 cn 许可值 cn,us手机号{"method":"mobile", "args":[]} {"method":"mobile", "args":["us"]}

加密方式

当前支持 AESPASSWORD 两种字段数值加密存储算法,其中 AES 仅支持 MySQL 数据库。

加密算法说明是否可逆
AESAES 加密,需设定 XIANG_DB_AESKEY
PASSWORDPASSWORD HASH 加密

保留字

以下名称不能用于字段名称。

保留字说明
created_at用于记录创建时间戳
updated_at用于记录更新时间戳
deleted_at用于记录软删除标记
__restore_data用于软删除时备份唯一字段数值

索引定义 indexes

一个数据模型,可以包含多个索引。对于单一索引,推荐在字段定义时,使用 indexuniqueprimary 修饰符定义,对于复合索引或全文检索索引,在 indexes 中定义。

{
"indexes": [
{
"comment": "厂商用户",
"name": "manu_id_mobile_unique",
"columns": ["manu_id", "mobile"],
"type": "unique"
},
{
"comment": "简历全文检索",
"name": "resume_fulltext",
"columns": ["resume"],
"type": "fulltext"
}
]
}
字段类型说明必填项
nameString索引名称。命名规范为 字段 1_字段 2_字段 n_索引类型
typeString索引类型 许可值 index 索引, unique 唯一索引, primary 主键, fulltext 全文检索
columnsArray\<String>关联字段名称列表(顺序有关) ["字段 1","字段 2"]["字段 2","字段 1"] 不同
commentString索引注释

关系映射 relations

数据模型支持一对一、一对多两种关系映射,可以通过定义映射关系将多个数据模型关联,查询时使用with参数即可同时返回关联模型数据。

映射关系名称关系说明
hasOne一对一模型 A 与模型 B 通过一对一关联
hasMany一对多模型 A 与模型 B 通过一对多关联

关联关系使用 [key:String]:Object Relation 数据结构定义 ( {"关联名称1":{}, "关联名称2":{}}, 关联名称为 小写英文字母 )

在模型文件 user.yao 中定义

查看源码

Object Relation

字段类型说明必填项
typeString关系类型 许可值 hasOne, hasOneThrough , hasMany , hasManyThrough
keyString关联模型的关联字段名称
modelString关联模型名称
foreignString当前模型的关联字段名称
queryObject QueryParam关系查询参数默认值。如在查询时未指定关联查询参数,则替使用在模型中定义的查询参数
linksArray\<Object Relation>hasOneThroughhasManyThrough 多表关联关系定义

hasOne 一对一

数据模型 user 数据表结构如下:

字段类型说明
idID用户 ID
manu_idbigInteger所属厂商 ID
namestring姓名

数据模型 manu 数据表结构如下:

字段类型说明
idID厂商 ID
shortstring厂商简称
companystring公司名称

在查询用户数据时,可以同时列出厂商信息或可以按关联厂商进行查询,则可以在定义 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.iduser.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 数据表结构如下:

字段类型说明
idID用户 ID
manu_idbigInteger所属厂商 ID
namestring姓名

数据模型 address 数据表结构如下:

字段类型说明
idID地址 ID
user_idbigInteger所属用户 ID (关联 user.id )
locationstring详细地址

对于类似一个用户有多个通信地址的业务场景,可以通过建立一对多的映射关系来实现。

在模型文件 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.idaddress.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
}
}
选项类型说明
timestampsBool为 true 时, 自动创建 created_atupdated_at 字段,并在插入和更新数据时,标记对应操作时间
soft_deletesBool为 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` asc
LIMIT 2

数据结构

QueryParam

字段类型说明必填项
selectArray\<String>选择字段清单
wheresArray\<Object Where>查询条件
ordersArray\<Object Order>排序条件
limitInteger返回记录条目
pageInteger当前页码
pagesizeInteger每页显示记录数量
withs[key:String]:Object With读取关联模型

Object Where

字段类型说明必填项
relString如按关联模型的字段查询,则填写关联模型名称
columnString字段名称
methodString查询方法 where,orwhere
opString匹配关系 eq,like,in,gt
valueAny匹配数值
wheresArray\<Object Where>分组查询
查询方法说明
whereWHERE 字段 = 数值, 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

字段类型说明必填项
relString如按关联模型的字段排序,则填写关联模型名称
columnString字段名称
optionString排序方式,默认为 asc desc, asc

Object With

字段类型说明必填项
nameString关联关系名称
queryObject QueryParam查询参数

完整示例

查看源码