gpt4 book ai didi

java - 使用 graphql-java-kickstart 库的 GraphQL 和数据加载器

转载 作者:行者123 更新时间:2023-12-01 16:28:45 27 4
gpt4 key购买 nike

我正在尝试使用 graphql-java-kickstart 库中的 DataLoader 功能:

https://github.com/graphql-java-kickstart

我的应用程序是使用 2.3.0.RELEASE 的 Spring Boot 应用程序。我使用的是 graphql-spring-boot-starter 库的 7.0.1 版本。

该库非常易于使用,并且当我不使用数据加载器时它可以工作。然而,我受到N+1 SQL问题的困扰,因此需要使用数据加载器来帮助缓解这个问题。当我执行请求时,我最终得到以下结果:

Can't resolve value (/findAccountById[0]/customers) : type mismatch error, expected type LIST got class com.daluga.api.account.domain.Customer

我确信我在配置中遗漏了一些东西,但真的不知道那是什么。

这是我的 graphql 架构:

type Account {
id: ID!
accountNumber: String!
customers: [Customer]
}

type Customer {
id: ID!
fullName: String
}

我创建了一个 CustomGraphQLContextBuilder:

@Component
public class CustomGraphQLContextBuilder implements GraphQLServletContextBuilder {

private final CustomerRepository customerRepository;

public CustomGraphQLContextBuilder(CustomerRepository customerRepository) {
this.customerRepository = customerRepository;
}

@Override
public GraphQLContext build(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
return DefaultGraphQLServletContext.createServletContext(buildDataLoaderRegistry(), null).with(httpServletRequest).with(httpServletResponse).build();
}

@Override
public GraphQLContext build(Session session, HandshakeRequest handshakeRequest) {
return DefaultGraphQLWebSocketContext.createWebSocketContext(buildDataLoaderRegistry(), null).with(session).with(handshakeRequest).build();
}

@Override
public GraphQLContext build() {
return new DefaultGraphQLContext(buildDataLoaderRegistry(), null);
}

private DataLoaderRegistry buildDataLoaderRegistry() {
DataLoaderRegistry dataLoaderRegistry = new DataLoaderRegistry();

dataLoaderRegistry.register("customerDataLoader",
new DataLoader<Long, Customer>(accountIds ->
CompletableFuture.supplyAsync(() ->
customerRepository.findCustomersByAccountIds(accountIds), new SyncTaskExecutor())));

return dataLoaderRegistry;
}
}

我还创建了一个 AccountResolver:

public CompletableFuture<List<Customer>> customers(Account account, DataFetchingEnvironment dfe) {
final DataLoader<Long, List<Customer>> dataloader = ((GraphQLContext) dfe.getContext())
.getDataLoaderRegistry().get()
.getDataLoader("customerDataLoader");

return dataloader.load(account.getId());
}

这是客户存储库:

public List<Customer> findCustomersByAccountIds(List<Long> accountIds) {

Instant begin = Instant.now();

MapSqlParameterSource namedParameters = new MapSqlParameterSource();
String inClause = getInClauseParamFromList(accountIds, namedParameters);

String sql = StringUtils.replace(SQL_FIND_CUSTOMERS_BY_ACCOUNT_IDS,"__ACCOUNT_IDS__", inClause);

List<Customer> customers = jdbcTemplate.query(sql, namedParameters, new CustomerRowMapper());

Instant end = Instant.now();

LOGGER.info("Total Time in Millis to Execute findCustomersByAccountIds: " + Duration.between(begin, end).toMillis());

return customers;
}

我可以在 Customer Repository 中放置一个断点,然后查看 SQL 的执行情况,它会返回一个 Customer 对象列表。您还可以看到该架构需要一组客户。如果我删除上面的代码并放入解析器来一一获取客户....它可以工作....但速度非常慢。

我在配置中缺少什么会导致这种情况?

Can't resolve value (/findAccountById[0]/customers) : type mismatch error, expected type LIST got class com.daluga.api.account.domain.Customer

感谢您的帮助!

最佳答案

谢谢,@Bms bharadwaj!我这边的问题是理解数据加载器中如何返回数据。我最终使用 MappedBatchLoader 将数据放入 map 中。映射中的键是 accountId。

private DataLoader<Long, List<Customer>> getCustomerDataLoader() {
MappedBatchLoader<Long, List<Customer>> customerMappedBatchLoader = accountIds -> CompletableFuture.supplyAsync(() -> {
List<Customer> customers = customerRepository.findCustomersByAccountId(accountIds);
Map<Long, List<Customer>> groupByAccountId = customers.stream().collect(Collectors.groupingBy(cust -> cust.getAccountId()));
return groupByAaccountId;
});
// }, new SyncTaskExecutor());

return DataLoader.newMappedDataLoader(customerMappedBatchLoader);
}

这似乎已经达到了目的,因为之前我发出了数百条 SQL 语句,现在减少到 2 条(一条用于驱动程序 SQL...帐户,一条用于客户)。

关于java - 使用 graphql-java-kickstart 库的 GraphQL 和数据加载器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62093189/

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