Spring Boot / GraphQL和SQL语句数(N + 1个问题)

问题描述 投票:2回答:1

我是Graphql的新手,正在寻求创建概念证明以了解其工作原理。我正在使用Spring Boot(2.2.2.RELEASE)并引入graphql-spring-boot-starter。

    <dependency>
        <groupId>com.graphql-java-kickstart</groupId>
        <artifactId>graphql-spring-boot-starter</artifactId>
        <version>6.0.1</version>
    </dependency>

我使用以下配置将我的graphql模式设置为类路径上的文件:

type Order {
  orderNumber: ID!
  customers: [Customer]
  items: [Item]
}

type Customer {
  customerNumber: ID!
  fullName: String
  postalAddresses: [PostalAddress]
}

type PostalAddress {
  line1: String
  line2: String
  city: String
  stateCode: String
  postalCode: String
  postalCodeExtension: String
  countryCode: String
}

type Item {
  itemId: ID!
  fullDescription: String
}

type Query {
  findOrdersByCustomerNumber(customerNumber: String): [Order]
}

我创建了根查询类:

@Component
public class Query implements GraphQLQueryResolver {
    private OrderService orderService;

    @Autowired
    public Query(OrderService orderService) {
        this.orderService = orderService;
    }

    public List<Order> findOrdersByCustomerNumber(String customerNumber) {
        return this.orderService.findOrdersByCustomerNumber(customerNumber);
    }
}

这是我的订单解析器:

@Component
public class OrderResolver implements GraphQLResolver<Order> {
    private ItemRepository itemRepository;
    private CustomerRepository customerRepository;

    @Autowired
    public OrderResolver(CustomerRepository customerRepository, ItemRepository itemRepository) {
        this.customerRepository = customerRepository;
        this.itemRepository = itemRepository;
    }

    public List<Item> item(Order order) {
        return itemRepository.findItemsByOrderNumber(order.getOrderNumber());
    }

    public List<Customer> customers(Order order) {
        return customerRepository.findCustomersByOrderNumber(order.getOrderNumber());
    }
}

一切似乎都可以正常工作,我可以发送graphql请求并获得响应。实际上,它真的很容易实现,并且让我对这个库的执行速度印象深刻。

但是,这是我的问题。这是可怕的n + 1 SQL问题。

所以,当我有162个订单的客户时。

  1 = Driver SQL (get all the orders for the customer number)
162 = Customer SQL (One query is fired off for each order and it's same customer for each select)
162 = Postal Address SQL (One query is fired off for each customer...note, not included in the code snippets)
162 = Item SQL (assume one item per order).

因此,总共有487个SQL查询。结果,这会影响性能。我正在使用直接JDBC查询数据库(目前尚无JPA或ORM)。

我的问题是如何在根查询解析器中保留GraphQL请求,以便可以为图中的依赖对象操纵SQL?在进行研究时,我发现在Node / Javacript世界中,有一个数据加载器实用程序可以帮助解决此问题(https://github.com/graphql/dataloader

因此,我不清楚如何通过此Java实现解决此问题。如果有人有任何建议或示例代码,那将很有帮助,以查看此POC是否具有任何优点。

感谢您的评论和建议。

谢谢,丹

java spring spring-boot graphql graphql-java
1个回答
© www.soinside.com 2019 - 2024. All rights reserved.