数据模型
目录
1. 概述
Yao 数据模型是应用的核心组件,它使系统能够:
- 自动数据迁移:根据模型定义创建和更新数据库表结构
- 元数据原子操作:提供标准化的数据操作方法
- 数据校验:基于模型定义进行输入数据的合法性验证
- 自动管理后台:生成数据管理界面
数据模型将操作方法映射为处理器(process),可在数据流(Flow)和接口(API)中直接调用。对于使用golang开发的业务插件,可通过Gou包访问模型方法。
2. 命名规范
数据模型使用小写英文字母命名的JSON文件:<name>.mod.json
| 文件位置 | 文件名 | 模型名称 | 处理器调用方式 |
|---|---|---|---|
| / | name.mod.json | name | models.name.<process> |
| /group/ | name.mod.json | group.name | models.group.name.<process> |
| /group1/group2/ | name.mod.json | group1.group2.name | models.group1.group2.name.<process> |
3. 文档结构
数据模型定义文件包含以下主要部分:
json
{
"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 | 配置选项 | ✗ |
3.1 基础信息
基础信息用于描述模型的元数据,便于在开发平台中管理和检索。
json
{
"name": "用户",
"version": "1.0.0",
"description": "网站用户元数据模型",
"author": "开发者姓名",
"email": "developer@example.com",
"license": "MIT"
}| 字段 | 类型 | 说明 | 必填 |
|---|---|---|---|
| name | String | 中文名称 | ✓ |
| version | String | 遵循语义化版本的版本号 | ✓ |
| description | String | 详细介绍 | ✗ |
| author | String | 作者 | ✗ |
| String | 联系方式 | ✗ | |
| license | String | 共享协议 | ✗ |
| homepage | String | 官网 | ✗ |
| tun | String | 象传智慧共享仓库地址,如microcity/petstore/user | ✗ |
3.2 数据表 table
定义模型对应的数据库表结构。
json
{
"table": {
"name": "user", // 表名
"comment": "用户表", // 表注释
"engine": "InnoDB" // 数据表引擎(MySQL)
}
}| 字段 | 类型 | 说明 | 必填 |
|---|---|---|---|
| name | String | 数据表名称 | ✓ |
| comment | String | 数据表注释 | ✗ |
| engine | String | 表引擎(MySQL),可选值:InnoDB、MyISAM | ✗ |
3.3 字段定义 columns
字段定义包含模型的各个属性及其验证规则。
json
{
"columns": [
{
"label": "ID",
"name": "id",
"type": "ID"
},
{
"label": "用户名",
"name": "username",
"type": "string",
"length": 50,
"comment": "登录用户名",
"nullable": false,
"unique": true,
"validations": [
{
"method": "typeof",
"args": ["string"],
"message": "用户名必须是字符串"
},
{
"method": "minLength",
"args": [3],
"message": "用户名至少需要3个字符"
}
]
}
]
}字段基本属性
| 字段 | 类型 | 说明 | 必填 |
|---|---|---|---|
| name | String | 字段名称 | ✓ |
| type | String | 字段类型 | ✓ |
| label | String | 显示名称 | ✓ |
| comment | String | 字段注释 | ✗ |
| length | Integer | 字段长度(适用于string等类型) | ✗ |
| precision | Integer | 数值总位数(适用于float等) | ✗ |
| scale | Integer | 小数位位数(适用于float等) | ✗ |
| option | Array<String> | 枚举类型选项 | ✗ |
| default | 任意 | 默认值 | ✗ |
| default_raw | String | 原始默认值(支持SQL函数) | ✗ |
| nullable | Boolean | 是否可为空(默认false) | ✗ |
| index | Boolean | 是否为索引(默认false) | ✗ |
| unique | Boolean | 是否为唯一索引(默认false) | ✗ |
| primary | Boolean | 是否为主键(默认false) | ✗ |
| crypt | String | 加密方式,可选值:AES、PASSWORD | ✗ |
| validations | Array<Object> | 验证规则 | ✗ |
字段类型对照表
| 类型 | 说明 | 参数 | MySQL对应类型 |
|---|---|---|---|
| string | 字符串 | length | VARCHAR(length) |
| text | 文本 | - | TEXT |
| integer | 整型 | - | INT |
| ID/id | 自增长整型 | - | BIGINT UNSIGNED AUTO_INCREMENT |
| float | 浮点数 | precision, scale | FLOAT(precision,scale) |
| decimal | 精确小数 | precision, scale | DECIMAL(precision,scale) |
| boolean | 布尔型 | - | BOOLEAN |
| enum | 枚举型 | option | ENUM(option...) |
| date | 日期 | - | DATE |
| datetime | 日期时间 | - | DATETIME |
| timestamp | 时间戳 | - | TIMESTAMP |
| json/JSON | JSON数据 | - | JSON |
完整字段类型列表请参考文档后面的详细说明
数据验证规则
验证规则用于在数据创建和更新时检查字段值的合法性。
json
{
"validations": [
{
"method": "typeof", // 验证方法
"args": ["string"], // 方法参数
"message": "必须是字符串" // 错误提示
}
]
}| 验证方法 | 参数 | 说明 | 示例 |
|---|---|---|---|
| typeof | [类型] | 检查数据类型 | {"method":"typeof", "args":["integer"]} |
| min | [最小值] | 最小值检查 | {"method":"min", "args":[0]} |
| max | [最大值] | 最大值检查 | {"method":"max", "args":[100]} |
| enum | [选项...] | 枚举值检查 | {"method":"enum", "args":["enabled","disabled"]} |
| pattern | [正则表达式] | 正则匹配 | {"method":"pattern", "args":["^1[3-9]\\d{9}$"]} |
| minLength | [长度] | 最小长度 | {"method":"minLength", "args":[6]} |
| maxLength | [长度] | 最大长度 | {"method":"maxLength", "args":[18]} |
| [] | 邮箱格式 | {"method":"email", "args":[]} | |
| mobile | [地区] | 手机号格式 | {"method":"mobile", "args":["cn"]} |
错误消息支持模板变量:
- 用户输入的值- 字段标签
字段加密
支持两种加密方式保护敏感数据:
| 加密方式 | 说明 | 可逆性 |
|---|---|---|
| AES | AES加密(需设置环境变量XIANG_DB_AESKEY) | 可逆 |
| PASSWORD | 密码哈希加密 | 不可逆 |
3.4 索引定义 indexes
索引用于提高查询性能和保证数据唯一性。
json
{
"indexes": [
{
"name": "user_email_mobile_unique", // 索引名称
"type": "unique", // 索引类型
"columns": ["email", "mobile"], // 索引字段
"comment": "用户邮箱和手机号唯一" // 索引说明
}
]
}| 字段 | 类型 | 说明 | 必填 |
|---|---|---|---|
| name | String | 索引名称(建议格式:字段1字段2..._索引类型) | ✓ |
| type | String | 索引类型:index、unique、primary、fulltext | ✓ |
| columns | Array<String> | 索引字段名称列表(顺序有关) | ✓ |
| comment | String | 索引注释 | ✗ |
3.5 关系映射 relations
关系映射定义模型之间的关联关系,支持一对一、一对多、多对多等多种映射方式。
json
{
"relations": {
"profile": {
// 关联名称
"type": "hasOne", // 关系类型
"model": "user_profile", // 关联模型
"key": "user_id", // 关联模型的关联字段
"foreign": "id", // 当前模型的关联字段
"query": {
// 默认查询参数
"select": ["avatar", "bio"]
}
}
}
}关系类型
| 关系类型 | 说明 | 用途 |
|---|---|---|
| hasOne | 一对一关系 | 用户-资料、产品-详情 |
| hasMany | 一对多关系 | 用户-订单、文章-评论 |
| hasOneThrough | 跨表一对一 | 复杂的间接关联 |
| hasManyThrough | 跨表一对多 | 用户-角色-权限 |
关系定义字段
| 字段 | 类型 | 说明 | 必填 |
|---|---|---|---|
| type | String | 关系类型 | ✓ |
| model | String | 关联模型名称 | ✓ (简单关系) |
| key | String | 关联模型关联字段 | ✓ (简单关系) |
| foreign | String | 当前模型关联字段 | ✓ (简单关系) |
| query | Object | 默认查询参数 | ✗ |
| links | Array<Object> | 多表关联定义 | ✓ (跨表关系) |
实际应用示例
一对一关系(hasOne):
json
{
"manu": {
"type": "hasOne",
"model": "manu",
"key": "id",
"foreign": "manu_id",
"query": { "select": ["name", "short_name"] }
}
}一对多关系(hasMany):
json
{
"addresses": {
"type": "hasMany",
"model": "address",
"key": "user_id",
"foreign": "id",
"query": {
"select": ["province", "city", "location"],
"limit": 20
}
}
}3.6 默认数据 values
定义模型的初始数据,在首次迁移时自动插入。
json
{
"values": [
{
"name": "管理员",
"email": "admin@example.com",
"password": "Admin@123",
"type": "admin",
"status": "enabled"
}
]
}3.7 配置选项 option
定义模型的全局配置参数。
json
{
"option": {
"timestamps": true, // 自动添加时间戳字段
"soft_deletes": true // 启用软删除
}
}| 选项 | 类型 | 说明 |
|---|---|---|
| timestamps | Boolean | 添加created_at和updated_at字段并自动维护 |
| soft_deletes | Boolean | 添加deleted_at字段实现软删除功能 |
4. 查询参数 QueryParam
查询参数用于在关系定义和API调用中描述数据过滤、排序和关联查询条件。
json
{
"select": ["id", "name", "mobile"], // 查询字段
"wheres": [
// 查询条件
{ "column": "status", "value": "enabled" }
],
"orders": [
// 排序条件
{ "column": "id", "option": "desc" }
],
"withs": {
// 关联查询
"profile": { "select": ["avatar"] }
},
"limit": 10, // 返回记录数
"page": 1, // 页码
"pagesize": 20 // 每页记录数
}查询条件格式
json
{
"wheres": [
{
"column": "status", // 字段名
"value": "enabled", // 匹配值
"op": "eq", // 操作符(可选,默认eq)
"method": "where" // 方法(可选,默认where)
},
{
"rel": "profile", // 关联模型名
"column": "is_verified", // 关联模型字段
"value": true
},
{
"wheres": [
// 分组条件(OR)
{ "column": "name", "value": "%张%", "op": "like" },
{ "method": "orwhere", "column": "name", "value": "%李%", "op": "like" }
]
}
]
}常用操作符
| 操作符 | 说明 | SQL等价 |
|---|---|---|
| eq | 等于(默认) | field = value |
| like | 模糊匹配 | field LIKE value |
| gt | 大于 | field > value |
| ge | 大于等于 | field >= value |
| lt | 小于 | field < value |
| le | 小于等于 | field <= value |
| in | 包含 | field IN (values) |
| null | 为空 | field IS NULL |
| notnull | 不为空 | field IS NOT NULL |
5. 处理器(process)
数据模型自动生成以下处理器,可在API和Flow中使用:
| 处理器 | 调用方式 | 功能 |
|---|---|---|
| find | models.模型名.find | 查询单条记录 |
| get | models.模型名.get | 按条件查询(不分页) |
| paginate | models.模型名.paginate | 按条件查询(分页) |
| create | models.模型名.create | 创建单条记录 |
| update | models.模型名.update | 更新单条记录 |
| save | models.模型名.save | 保存记录(存在则更新,不存在则创建) |
| delete | models.模型名.delete | 删除单条记录(软删除) |
| destroy | models.模型名.destroy | 删除单条记录(物理删除) |
| insert | models.模型名.insert | 批量插入记录 |
| updatewhere | models.模型名.updatewhere | 按条件更新记录 |
| deletewhere | models.模型名.deletewhere | 按条件删除记录(软删除) |
| destroywhere | models.模型名.destroywhere | 按条件删除记录(物理删除) |
| eachsave | models.模型名.eachsave | 批量保存记录 |
6. 完整示例
以下是一个完整的用户模型定义示例:
json
{
"name": "用户",
"table": {
"name": "user",
"comment": "用户信息表",
"engine": "InnoDB"
},
"columns": [
{ "label": "ID", "name": "id", "type": "ID" },
{
"label": "用户名",
"name": "username",
"type": "string",
"length": 50,
"unique": true,
"comment": "登录用户名",
"validations": [
{
"method": "typeof",
"args": ["string"],
"message": "{{label}}必须是字符串"
},
{
"method": "minLength",
"args": [3],
"message": "{{label}}长度至少为3个字符"
}
]
},
{
"label": "密码",
"name": "password",
"type": "string",
"length": 256,
"comment": "登录密码",
"crypt": "PASSWORD",
"validations": [
{
"method": "pattern",
"args": [
"^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&])[A-Za-z\\d@$!%*?&]{8,}$"
],
"message": "{{label}}必须包含大小写字母、数字和特殊字符,且长度不少于8位"
}
]
},
{
"label": "状态",
"name": "status",
"type": "enum",
"option": ["active", "inactive", "banned"],
"default": "inactive",
"comment": "用户状态",
"index": true
}
],
"indexes": [
{
"name": "username_status_index",
"comment": "用户名和状态联合索引",
"columns": ["username", "status"],
"type": "index"
}
],
"relations": {
"profile": {
"type": "hasOne",
"model": "user_profile",
"key": "user_id",
"foreign": "id"
},
"orders": {
"type": "hasMany",
"model": "order",
"key": "user_id",
"foreign": "id",
"query": { "limit": 10 }
}
},
"values": [
{
"username": "admin",
"password": "Admin@123",
"status": "active"
}
],
"option": {
"timestamps": true,
"soft_deletes": true
}
}