gpt4 book ai didi

graphql-java - 如何使用 graphql-jpa java 解决 graphql n+1 问题?

转载 作者:行者123 更新时间:2023-12-01 07:23:59 33 4
gpt4 key购买 nike

我面对的是graphql n+1在我的一个应用程序中出现问题,我在 java 中使用带有 restful webservice 的 graphql。我正在使用 schemagen-graphqlspring-data-jpa用于连接到我的 oracle 数据库。
我看到了很多帖子,但大多数答案都是graphql-node.js执行。任何与java相关的东西都会很好。

最佳答案

我不太了解schemagen-graphql以及这里是否重要,但总的来说,graphql-java 目前有 3 个选项:

  • 在解析父字段时预取您需要的内容(即在父字段的 DataFetcher 中)。您可以通过检查 DataFetchingFieldSelectionSet 来准确查看请求的子字段。 .
    如果预取的数据不适合结果对象,您可以将其存储在 LocalContext 中。并在解析子字段值时使用它。 this blog post 中很好地解释了这种方法。 .
  • 使用 已弃用 (如果您使用 graphql.execution 下的类)或 实验 (如果使用 graphql.execution.nextgen 下的类)使用 @Batched 注释数据 getter 的方法并使用 BatchedExecutionStrategy .
    此选项易于理解和使用,但会将您与 BatchedExecutionStrategy 联系起来。 (旧版本在处理空值时并未完全遵守规范)。
    遗憾的是,它的记录很差,但归结为:
  • 注释DataFetcher#get使用 @Batched 的方法
  • 在那个数据提取器中,DataFetchingEnvironment#getSource将始终返回源对象列表(而不是一个)。
  • 这样的数据 getter 必须始终返回结果列表(与源列表的长度相同)。这允许以简单的方式批量加载对象。一个明显的例子是一次从关系数据库中加载许多行:

  • List<Article> articles = DataFetchingEnvironment.getSource(); //source is a list
    List<Long> authorIds = articles.stream.map(article -> article.getAuthodId()).collect(Collectors.toList());

    //fetch all the authors in one go
    SELECT * FROM Author WHERE author_id IN (authorIds)

  • 使用 DataLoader 获取您的数据而不是直接获取它。这个想法与最初的数据加载器 JavaScript 库非常相似。仅适用于默认 AsyncExecutionStrategy仅用于查询 (所以不要指望它适用于突变和订阅)。

  • 您可以提供 DataLoaderRegistry 的实例在 ExecutionInput ,并且您通常希望在每个请求上重新创建数据加载器和注册表(如果它们是无状态的,则可以共享批处理加载器):
    DataLoaderRegistry loaders = ...; //initialize your loaders, usually per request

    graphQL.execute(ExecutionInput.newExecutionInput()
    .query(operation)
    .dataLoaderRegistry(loaders) //add the registry to input
    .build());

    然后在你的 DataFetcher您可以随时访问 DataLoader 您需要通过 DataFetchingEnvironment#getDataLoader(String dataLoaderName) :
    return env.getDataLoader("authors").load(article.getAuthorId());

    作为旁注,您可能想查看我自己的库,用于从 Java 生成 GraphQL API, GraphQL-SPQR .这里是 a minimal demonstration使用 @Batched用它。

    至于DataLoader,逻辑同上,到 DataLoaderRegistry通过 @GraphQLEnvironment注解:
    @GrapgQLQuery
    public CompletableFuture<Author> author(@GraphQLContext Article article, @GraphQLEnvironment ResolutionEnvironment env) {
    return env.dataFetchingEnvironment.getDataLoader("authors").load(article.getAuthorId())
    }

    我可能还会添加一个专门的注释,如 @DataLoader("authors")用于直接注入(inject)加载程序。

    关于graphql-java - 如何使用 graphql-jpa java 解决 graphql n+1 问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47674981/

    33 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com