当前位置: 首页 > 知识库问答 >
问题:

GraphQLJava:分组SQL和映射

邢焕
2023-03-14

我正在构建图形ql-javaSpring引导应用程序。假设我有这个模式:

type Foo {
id: ID! name: String bars: [Bar]
}
type Bar {
id: ID! name: String
}
query{
  foo(arg: String): [Foo]
}

在BE上,我使用的是JOOQ pojos。

当前,所有的foo都被提取,然后对于每个foo,所有的条都通过另一个查询提取。我想通过一个查询来实现这一点:

select * from foo 
left join bar on foo.id = bar.foo_id;

你知道如何做到这一点吗?我是一个真正的GraphQL新手。

技术堆栈:Spring Boot JOOQ graphql java graphql java工具

共有1个答案

曾华翰
2023-03-14

在您的简单示例中,LEFT JOIN绝对是一个选项。这就是像JPA/Hibernate这样的ORM在后台获取嵌套集合时所做的工作。该战略有一些缺点:

  • 有数据重复。对于每个BAR(子表),您将复制匹配的FOO(父表)的数据。这可导致在导线上传送的大量开销。你需要的连接越多(即嵌套越多),情况就会越来越糟
  • 有笛卡尔产品。如果要一次完成,则不能在子表之间嵌套多个集合而不产生笛卡尔产品。使用笛卡尔产品,很难“记住”,哪些组合实际上是合法的,哪些是连接树的工件。因此,您将返回到运行几个查询,每个嵌套树分支一个

但是,有一个更好的方法,从JOOQ3.14开始。您可以使用XML或JSON,具体取决于您使用的数据库方言。这里的关键特性是XMLAGGJSON_ARRAYAGG,它们允许将数据聚合到XML元素或JSON对象中。因为您将使用GraphQL生成JSON文档,所以我猜您将使用JSON。

使用标准SQL(如Oracle实现的),您为示例生成的SQL查询可以如下所示:

SELECT
  JSON_ARRAYAGG(
    JSON_OBJECT(
      KEY "id" VALUE foo.id,
      KEY "name" VALUE foo.name,
      KEY "bars" VALUE (
        SELECT 
          JSON_ARRAYAGG(
            JSON_OBJECT(
              KEY "id" VALUE bar.id,
              KEY "name" VALUE bar.name
            )
          )
        FROM bar
        WHERE bar.foo_id = foo.id
      )
    )
  )
FROM foo

目前,这些方言应该能够支持jsonArrayAgg()jsonObject()(或其模拟,例如在PostgreSQL中):

  • 蟑螂B
  • Db2 LUW 11
  • H2
  • MariaDB 10.2
  • MySQL 5.7
  • Oracle 12c
  • PostgreSQL

更多详情请参阅本博客文章。

在SQL服务器中使用FOR JSON的仿真在将来也是可能的。

请注意,JSON_ARRAYAGG()将空集聚合为NULL,而不是将其聚合为空的[]。如果这是一个问题,使用COALESCE()

事实上,我以前也想过,开箱即用。我们可能会在不久的将来这样做:https://github.com/jOOQ/jOOQ/issues/10122

 类似资料:
  • 在本书的这一部分中,我们将介绍一些内容,它们与本书其余部分的结构不相符,但对于初级开发人员来说,这是非常必要的主题。了解如何在 SQL 数据库中构造数据,会教给你如何在逻辑上思考数据存储需求。有一个建立已久的方法来解构数据,有效存储数据和访问数据。近年来 NoSQL 数据库的发展使其不同,但关系数据库设计背后的基本概念仍然有用。在你需要存储数据的每个地方,都需要良好地构造并理解数据。 大多数这些练

  • 我想在sql语句中使用一个名为tags的参数: 我通过以下方式传递参数并执行语句: 如果我将语句更改为: 它抛出错误: 类org.springframework.jdbc.badsqlgrammareXception PreparedStatementCallback;错误的SQL语法[SELECT*FROM reply WHERE(?,?)@>array[2293,2294];嵌套异常是org.

  • 问题内容: 我有以下几点: http://sqlfiddle.com/#!6/226ae/1 我现在尝试为一年中的每个星期添加一行,并相应地过滤联系人。CONTACTS有一个datetime列。新表将如下所示: 我认为需要使用DATEADD,但是在如何开始更改查询方面我迷茫了。 我确实知道MySQL具有GROUP BY WEEK命令,但我认为SQL没有等效的命令。做到这一点的最佳方法是什么? 问题

  • 流上的操作是否可以生成一个映射,其中值是数组而不是列表或其他集合类型? 例如:我有一个类。事物有所有者,所以有一个方法。在一个事物流中,我想按所有者ID对事物进行分组,以便具有相同所有者ID的事物最终在一个数组中。换句话说,我想要一个像下面这样的映射,其中键是所有者ID,值是属于该所有者的事物数组。 在我的例子中,因为我需要将映射值传递给一个需要数组的库方法,所以收集到一个< code >映射中是

  • 问题内容: 我有一个包含JSON对象的表。每个JSON对象在方括号中均包含一个数组,并用逗号分隔。 如何使用SQL访问方括号数组中的任何元素,例如“ Matt”? 我在Hadoop上使用“ Hive”。如果您知道如何在SQL中执行此操作,那很好:) 问题答案: 您可以在Hive中执行以下操作: 首先,您需要一个JSON SerDe(Serializer / Deserializer)。我见过的最实

  • 问题内容: 我有以下SQL: 输出如下: 我希望能够仅获取一个代码并获得最近的距离。所以我希望它返回这个: 我最初有这样的东西: 如果我不想获得与最小距离相关联的正确位置,则最小值显示效果很好。如何获取最小距离(和距离)以及正确的位置(取决于表格中插入内容的顺序,有时您可能会得到纽约距离,但夏洛特位于“位置”)。 问题答案: 为了获得正确的关联位置,您需要加入一个子选择,该子选择在外部主表中的距离