GraphQL 关系查询
数据墙DBW 的 GraphQL 端点支持在实体之间定义关系,让客户端在一次请求中获取关联数据。关系查询不需要写 JOIN——配置好实体间的关联后,GraphQL 架构会自动生成嵌套字段。
NOTE
关系查询仅适用于 GraphQL。REST API 不支持嵌套关联数据的查询。
配置关系
关系在 entities 块中通过 relationships 字段配置:
{
"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_category | category |
category_books | books |
books_authors | authors |
引擎会去掉源实体名称前缀,保留目标部分并转换为 camelCase。如果关系名称与目标实体名相同(如 Category 中定义 books 指向 Book),则直接使用该名称。
CLI 添加关系
dab update Book \
--relationship book_category \
--target.entity Category \
--cardinality one \
--relationship.fields "category_id:id"三种关系基数
| 基数 | 说明 | 示例 |
|---|---|---|
one | 一对一或多对一 | 一本书属于一个分类 |
many | 一对多或多对多 | 一个分类下有多本书 |
多对一关系
一本书属于一个分类(Book.category_id → Category.id):
{
"Book": {
"relationships": {
"book_category": {
"cardinality": "one",
"target.entity": "Category",
"source.fields": ["category_id"],
"target.fields": ["id"]
}
}
}
}查询时,category 作为嵌套字段出现:
{
books {
items {
id
title
category {
id
name
}
}
}
}响应中每条 Book 记录都内嵌了对应的 Category 对象:
{
"data": {
"books": {
"items": [
{
"id": 1,
"title": "Dune",
"category": { "id": 10, "name": "科幻" }
}
]
}
}
}一对多关系
一个分类下有多本书(Category.id ← Book.category_id):
{
"Category": {
"relationships": {
"category_books": {
"cardinality": "many",
"target.entity": "Book",
"source.fields": ["id"],
"target.fields": ["category_id"]
}
}
}
}查询时,关联集合使用 Connection 模式(分页结构):
{
categories {
items {
name
books {
items { id title }
}
}
}
}一对多关系的嵌套字段遵循标准的分页结构,包含 items 数组。
多对多关系
多对多需要第三张关联表(联接表)。例如 Book 和 Author 通过 dbo.books_authors 关联:
{
"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 | 联接表中指向目标实体的字段 |
查询方式与一对多相同:
{
books {
items {
title
authors {
items { firstName: first_name lastName: last_name }
}
}
}
}嵌套字段选择与别名
关系查询中,可以为关联实体的字段使用别名:
{
books {
items {
title
bookCategory: category { id catName: name }
bookAuthors: authors { items { authorName: name } }
}
}
}多层嵌套
关系可以跨越多层:
{
books {
items {
title
category {
name
parentCategory {
name
}
}
}
}
}每层嵌套字段都独立,需要各层关系的配置才能生效。没有配置关系的跳转无法嵌套。
NOTE
过深的嵌套查询可能导致大量数据库查询。建议设置 runtime.graphql.depth-limit 来控制最大嵌套深度。
重要限制
| 限制 | 说明 |
|---|---|
| 仅 GraphQL | REST 不支持关系查询 |
| 跨文件不可用 | 不同配置文件中定义的实体不能建立关系 |
| 视图不支持 | 视图实体不能配置 relationships |
| 存储过程不支持 | 存储过程实体也不支持 |
| 同库限制 | 关联的两个实体必须在同一个数据库中 |
关系配置字段速查
| 字段 | 必需 | 说明 |
|---|---|---|
cardinality | 是 | one 或 many |
target.entity | 是 | 目标实体名称 |
source.fields | 视情况 | 源实体的关联字段 |
target.fields | 视情况 | 目标实体的关联字段 |
linking.object | 多对多 | 联接表名称 |
linking.source.fields | 多对多 | 联表中指向源的字段 |
linking.target.fields | 多对多 | 联表中指向目标的字段 |
下一步
- GraphQL 聚合查询 — 服务端统计计算。
- 配置实体 — 关系配置参考。
