Skip to content

GraphQL 关系查询

数据墙DBW 的 GraphQL 端点支持在实体之间定义关系,让客户端在一次请求中获取关联数据。关系查询不需要写 JOIN——配置好实体间的关联后,GraphQL 架构会自动生成嵌套字段。

NOTE

关系查询仅适用于 GraphQL。REST API 不支持嵌套关联数据的查询。

配置关系

关系在 entities 块中通过 relationships 字段配置:

json
{
  "entities": {
    "Book": {
      "source": { "object": "dbo.books", "type": "table" },
      "relationships": {
        "book_category": {
          "cardinality": "one",
          "target.entity": "Category",
          "source.fields": ["category_id"],
          "target.fields": ["id"]
        }
      }
    },
    "Category": {
      "source": { "object": "dbo.categories", "type": "table" },
      "relationships": {
        "category_books": {
          "cardinality": "many",
          "target.entity": "Book",
          "source.fields": ["id"],
          "target.fields": ["category_id"]
        }
      }
    }
  }
}

关系是双向可配置的——可以在 Book 中定义指向 Category 的关系,也在 Category 中定义指向 Book 的关系。

关系名称到 GraphQL 字段名

配置中的关系名称(如 book_category)会自动转换为 camelCase 作为 GraphQL 查询字段名(如 bookCategory)。转换规则:

配置中的关系名称GraphQL 查询字段名
book_categorycategory
category_booksbooks
books_authorsauthors

引擎会去掉源实体名称前缀,保留目标部分并转换为 camelCase。如果关系名称与目标实体名相同(如 Category 中定义 books 指向 Book),则直接使用该名称。

CLI 添加关系

bash
dab update Book \
  --relationship book_category \
  --target.entity Category \
  --cardinality one \
  --relationship.fields "category_id:id"

三种关系基数

基数说明示例
one一对一或多对一一本书属于一个分类
many一对多或多对多一个分类下有多本书

多对一关系

一本书属于一个分类(Book.category_idCategory.id):

json
{
  "Book": {
    "relationships": {
      "book_category": {
        "cardinality": "one",
        "target.entity": "Category",
        "source.fields": ["category_id"],
        "target.fields": ["id"]
      }
    }
  }
}

查询时,category 作为嵌套字段出现:

graphql
{
  books {
    items {
      id
      title
      category {
        id
        name
      }
    }
  }
}

响应中每条 Book 记录都内嵌了对应的 Category 对象:

json
{
  "data": {
    "books": {
      "items": [
        {
          "id": 1,
          "title": "Dune",
          "category": { "id": 10, "name": "科幻" }
        }
      ]
    }
  }
}

一对多关系

一个分类下有多本书(Category.idBook.category_id):

json
{
  "Category": {
    "relationships": {
      "category_books": {
        "cardinality": "many",
        "target.entity": "Book",
        "source.fields": ["id"],
        "target.fields": ["category_id"]
      }
    }
  }
}

查询时,关联集合使用 Connection 模式(分页结构):

graphql
{
  categories {
    items {
      name
      books {
        items { id title }
      }
    }
  }
}

一对多关系的嵌套字段遵循标准的分页结构,包含 items 数组。

多对多关系

多对多需要第三张关联表(联接表)。例如 BookAuthor 通过 dbo.books_authors 关联:

json
{
  "Book": {
    "relationships": {
      "books_authors": {
        "cardinality": "many",
        "target.entity": "Author",
        "source.fields": ["id"],
        "target.fields": ["id"],
        "linking.object": "dbo.books_authors",
        "linking.source.fields": ["book_id"],
        "linking.target.fields": ["author_id"]
      }
    }
  }
}

多对多关系的核心字段:

字段说明
linking.object联接表的名称
linking.source.fields联接表中指向源实体的字段
linking.target.fields联接表中指向目标实体的字段

查询方式与一对多相同:

graphql
{
  books {
    items {
      title
      authors {
        items { firstName: first_name lastName: last_name }
      }
    }
  }
}

嵌套字段选择与别名

关系查询中,可以为关联实体的字段使用别名:

graphql
{
  books {
    items {
      title
      bookCategory: category { id catName: name }
      bookAuthors: authors { items { authorName: name } }
    }
  }
}

多层嵌套

关系可以跨越多层:

graphql
{
  books {
    items {
      title
      category {
        name
        parentCategory {
          name
        }
      }
    }
  }
}

每层嵌套字段都独立,需要各层关系的配置才能生效。没有配置关系的跳转无法嵌套。

NOTE

过深的嵌套查询可能导致大量数据库查询。建议设置 runtime.graphql.depth-limit 来控制最大嵌套深度。

重要限制

限制说明
仅 GraphQLREST 不支持关系查询
跨文件不可用不同配置文件中定义的实体不能建立关系
视图不支持视图实体不能配置 relationships
存储过程不支持存储过程实体也不支持
同库限制关联的两个实体必须在同一个数据库中

关系配置字段速查

字段必需说明
cardinalityonemany
target.entity目标实体名称
source.fields视情况源实体的关联字段
target.fields视情况目标实体的关联字段
linking.object多对多联接表名称
linking.source.fields多对多联表中指向源的字段
linking.target.fields多对多联表中指向目标的字段

下一步

数据墙DBW 产品文档与开发指南。