数据模型关联 
基本概念 
Yao DSL支持两种数据模型关联类型:
- hasOne:一对一关联,表示当前模型的一条记录对应关联模型的一条记录
 - hasMany:一对多关联,表示当前模型的一条记录对应关联模型的多条记录
 
通过使用withs参数,可以在查询时同时获取关联数据,避免多次查询,提高效率。
实例说明 
以下我们通过供应商(supplier)和用户(user)两个模型演示关联关系:
- 一个用户对应一家供应商 (用户 -> 供应商 = hasOne)
 - 一家供应商有多个用户 (供应商 -> 用户 = hasMany)
 
数据结构设计 
供应商模型 (supplier) 
字段结构:
| 字段 | 标签 | 说明 | 
|---|---|---|
| id | ID | 主键 | 
| name | 名称 | 供应商名称 | 
示例数据:
| ID | 名称 | 
|---|---|
| 1 | 象传智慧 | 
| 2 | Yao App Engine | 
用户模型 (user) 
字段结构:
| 字段 | 标签 | 说明 | 
|---|---|---|
| id | ID | 主键 | 
| supplier_id | 所属供应商 ID | 外键,关联供应商表 | 
| name | 姓名 | 用户姓名 | 
示例数据:
| ID | supplier_id | name | 
|---|---|---|
| 1 | 1 | 张无忌 | 
| 2 | 1 | 李光富 | 
| 3 | 2 | 李木婷 | 
| 4 | 2 | 赵长青 | 
模型定义文件 
供应商模型定义 (supplier.mod.json) 
json
{
  "name": "供应商",
  "table": { "name": "supplier", "comment": "供应商表" },
  "columns": [
    {
      "label": "ID",
      "name": "id",
      "type": "ID",
      "comment": "ID"
    },
    {
      "label": "名称",
      "name": "name",
      "type": "string",
      "index": true,
      "comment": "供应商名称"
    }
  ],
  "relations": {
    "users": {
      "name": "users", // 关联名称,查询时通过此名称引用
      "type": "hasMany", // 关系类型:一对多
      "model": "user", // 关联的模型名称
      "key": "supplier_id", // 关联模型中的关联字段
      "foreign": "id", // 当前模型中的关联字段
      "query": { "select": ["id", "name"] } // 默认查询字段
    }
  },
  "values": [
    { "id": 1, "name": "象传智慧" },
    { "id": 2, "name": "Yao App Engine" }
  ]
}用户模型定义 (user.mod.json) 
json
{
  "name": "用户",
  "table": { "name": "user", "comment": "用户表" },
  "columns": [
    { "label": "ID", "name": "id", "type": "ID", "comment": "ID" },
    {
      "label": "供应商",
      "name": "supplier_id",
      "type": "bigInteger",
      "index": true,
      "comment": "供应商ID"
    },
    {
      "label": "姓名",
      "name": "name",
      "type": "string",
      "index": true,
      "comment": "用户姓名"
    }
  ],
  "relations": {
    "supplier": {
      "name": "supplier", // 关联名称,查询时通过此名称引用
      "type": "hasOne", // 关系类型:一对一
      "model": "supplier", // 关联的模型名称
      "key": "id", // 关联模型中的关联字段
      "foreign": "supplier_id", // 当前模型中的关联字段
      "query": { "select": ["id", "name"] } // 默认查询字段
    }
  },
  "values": [
    { "id": 1, "supplier_id": 1, "name": "张无忌" },
    { "id": 2, "supplier_id": 1, "name": "李光富" },
    { "id": 3, "supplier_id": 2, "name": "李木婷" },
    { "id": 4, "supplier_id": 2, "name": "赵长青" }
  ]
}数据表创建 
使用以下命令创建数据表:
bash
yao migrate关联关系声明详解 
关联关系通过模型定义中的 relations 对象声明,支持多个映射关系。
关联关系对象字段说明 
| 字段 | 类型 | 必填 | 说明 | 
|---|---|---|---|
| name | string | 是 | 关联名称,查询时的引用标识符 | 
| type | string | 是 | 关系类型:hasOne(一对一) 或 hasMany(一对多) | 
| model | string | 是 | 关联模型名称 | 
| key | string | 是 | 关联模型中用于关联的字段名称 | 
| foreign | string | 是 | 当前模型中用于关联的字段名称 | 
| query | object | 否 | 关联模型的默认查询条件,可在实际查询时重载 | 
hasOne 关联使用示例 
hasOne 表示"拥有一个"关系,如用户拥有一个供应商的关联。
基本查询 
查询用户并同时获取供应商信息:
bash
# 查询ID为1的用户及其供应商信息
yao run models.user.Find 1 '::{"withs":{ "supplier": {} }}'
# 查询所有用户及其供应商信息
yao run models.user.Get '::{"withs":{ "supplier": {} }}'指定关联字段 
bash
# 仅查询供应商的name字段
yao run models.user.Find 1 '::{"withs":{ "supplier": {"query":{ "select":["name"] }} }}'按关联字段条件筛选 
bash
# 查询供应商名称为"Yao App Engine"的用户
yao run models.user.Get '::{"withs":{ "supplier": {} }, "wheres":[{"rel":"supplier", "column":"name", "value":"Yao App Engine" }]}'JavaScript中使用关联查询 
javascript
function test() {
  var user = Process('models.user.get', {
    withs: {
      supplier: {
        // 关联供应商表
        query: {
          select: ['name', 'id'] // 指定查询字段
        }
      }
    },
    wheres: [{ column: 'supplier_id', value: 1, op: '=' }], // 查询条件
    orders: [{ column: 'id', option: 'desc' }], // 排序条件
    limit: 1 // 限制返回条数
  });
}hasMany 关联使用示例 
hasMany 表示"拥有多个"关系,如供应商拥有多个用户的关联。
基本查询 
bash
# 查询ID为1的供应商及其所有用户
yao run models.supplier.Find 1 '::{"withs":{ "users": {} }}'
# 查询所有供应商及其所有用户
yao run models.supplier.Get '::{"withs":{ "users": {} }}'指定关联字段 
bash
# 仅查询用户的name字段
yao run models.supplier.Find 1 '::{"withs":{ "users": { "query":{"select":["name"] }} }}'关联数据筛选 
bash
# 查询名为"张无忌"的用户所属的供应商
yao run models.supplier.Find 1 '::{"withs":{ "users": { "wheres":[{"column":"name", "value":"张无忌"}] } }}'嵌套关联查询 
关联关系支持嵌套查询,可以通过多层 withs 参数实现。
多层嵌套示例 
bash
# 查询供应商及其用户,同时查询用户的供应商信息(形成循环引用)
yao run models.supplier.Find 1 '::{"withs":{ "users": { "withs": {"supplier":{} } } }}'
# 查询所有供应商的嵌套数据
yao run models.supplier.Get '::{"withs":{ "users": { "withs": {"supplier":{} } } }}'注意事项 
- 嵌套查询可能导致数据量过大,请谨慎使用深层嵌套
 - 关联查询会增加数据库负担,请只查询必要字段
 - 复杂的关联查询建议在后端处理而非直接通过API查询
 
通过合理使用数据模型关联,可以大幅简化数据查询逻辑,提高开发效率。