DataLoader批量加载错误(MyBatis,JavaEE)
我的产品中有graphql,禁止共享代码。我使用的是GraphQLJavaservlet,就像我使用MyBatis的ORM一样DataLoader批量加载错误(MyBatis,JavaEE),java,graphql,jax-rs,mybatis,java-ee-7,Java,Graphql,Jax Rs,Mybatis,Java Ee 7,我的产品中有graphql,禁止共享代码。我使用的是GraphQLJavaservlet,就像我使用MyBatis的ORM一样 <dependency> <groupId>com.graphql-java-kickstart</groupId> <artifactId>graphql-java-servlet</artifactId> <version>9.2.0</version>
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-java-servlet</artifactId>
<version>9.2.0</version>
</dependency>
因此,在fetcher中,我将有2个请求:
childDataLoader.loadMany({1,3,5})
childDataLoader.loadMany({2,4,6})
"data": {
"parents": [
{
"id": 1,
"childs": [
{
"id": 1,
},
{
"id": 2,
},
{
"id": 3,
}
},
{
"id": 2,
"childs": [
{
"id": 4,
},
{
"id": 5,
},
{
"id": 6,
}
}
]
}
]
}
回答的顺序必须与请求的顺序相同, 如果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()));
};
private BatchLoader buildBatchLoader(){
返回列表->CompletableFuture.SupplySync(()->
childService.findByIds(list.stream)()
.排序(比较器.比较长(实体->
list.indexOf(entity.getId()))
.collect(Collectors.toList());
};
通常情况下,根据输入ID的顺序对childService#findByIds的结果进行排序应该是一个好办法。您确定输入id列表的顺序已经混乱了吗?您是否使用调试器进行了验证?是的,我使用调试器进行了验证,如果我尝试像这样执行smt,sql响应的排序现在会很有帮助:childService.findByIds(list)。然后应用(listentyes->{long count=listentyes.stream().filter(entitye->!listIds.contains((entitye.getId()))).count();if(count>0){抛出新异常(“不同的sql请求和响应”);}返回它;})代码>如果您在CompletableFuture.SupplySync(()->childService.findByIds(列表));,中设置断点,我将得到一个例外;,列表的顺序是否仍然正确?我想我找到了解决方案,而且我遗漏了一些排序,这破坏了DataLoader的顺序。我将检查,如果是,我将更改我的问题并提供答案
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)
}
}
parents: [
{
"id": 1
"childIds": {1,3,5}
},
{
"id": 2
"childIds": {2,4,6}
}
]
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,
}
}
]
}
]
}
private BatchLoader<Long, Child> buildBatchLoader() {
return list -> CompletableFuture.supplyAsync(() ->
childService.findByIds(list).stream()
.sorted(Comparator.comparingLong(entity ->
list.indexOf(entity.getId())))
.collect(Collectors.toList()));
};