数据模型 
目录 
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
  }
}