我的产品中有graphql,禁止共享代码。我使用,就像ORM使用MyBatis一样。
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-java-servlet</artifactId>
<version>9.2.0</version>
</dependency>启用BatchLoading之后,我发现graphQL DataLoader混淆了批处理请求实体的位置。此外,如果查看futureCacheMap,很容易检查,您会发现Key(Id)和Value(实体)有不同的Id。
调试后,我没有找到graphQL如何在batchLoading (1000PSC)之后解析实体。所以我决定我应该有一些排序,所以我实现了它,但它没有解决问题。
例如:我有Parent.class,里面有孩子。
class Parent {
private Long id;
private List<Long> childsIds;
}我有ChildDataloader
private BatchLoader<Long, Child> buildBatchLoader() {
return list -> > CompletableFuture.supplyAsync(() -> childService.findByIds(list));
}
private DataLoader<Long, Child> buildDataLoader(BatchLoader batchLoader) {
DataLoaderOptions options = DataLoaderOptions.newOptions();
options.setMaxBatchSize(1000);
return new DataLoader<Long, Child>(batchLoader, options);
}
}我有ChildsFetcher,在这里我调用了dataLoader.loadMany()
public class ChildsFetcher implements DataFetcher<CompletableFuture<List<Child>>>{
private static final String PK_FIELD_NAME = "childsIds";
@Override
public CompletableFuture<List<LoadDefinitionDTO>> get(DataFetchingEnvironment environment) {
GraphQLContext context = environment.getContext();
DataLoaderRegistry dataLoaderRegistry = context.getDataLoaderRegistry().orElseThrow(
() -> new DalException("there was no dataLoaderRegistry in context", Response.Status.INTERNAL_SERVER_ERROR)
);
List<Long> childsIds = getParentFieldValue(environment, PK_FIELD_NAME , List.class);
DataLoader<Long, Child> childDataLoader = dataLoaderRegistry.getDataLoader("childDataLoader");
return childDataLoader.loadMany(childsIds)
}
}例如,我有两个父母,每个有3个孩子。
parents: [
{
"id": 1
"childIds": {1,3,5}
},
{
"id": 2
"childIds": {2,4,6}
}
]因此,在获取器中,我将有两个请求:
childDataLoader.loadMany({1,3,5})childDataLoader.loadMany({2,4,6})在Dataloader中,它将只有一个(如预期的那样),但是查看I的顺序(我无法控制它):
childService.findByIds({1,3,5,2,4,6})在产出中,我将收到:
"data": {
"parents": [
{
"id": 1,
"childs": [
{
"id": 1,
},
{
"id": 2,
},
{
"id": 3,
}
},
{
"id": 2,
"childs": [
{
"id": 4,
},
{
"id": 5,
},
{
"id": 6,
}
}
]
}
]
}发布于 2020-08-28 10:54:48
您的回答顺序必须与请求的顺序相同,如果ORM对sql响应进行排序,只需在从ORM获得响应后将其恢复到DataLoader中,例如:
private BatchLoader<Long, Child> buildBatchLoader() {
return list -> CompletableFuture.supplyAsync(() ->
childService.findByIds(list).stream()
.sorted(Comparator.comparingLong(entity ->
list.indexOf(entity.getId())))
.collect(Collectors.toList()));
}; https://stackoverflow.com/questions/63630507
复制相似问题