【问题标题】:Why does graphql java query all fields in entity when I only ask for a few?当我只要求几个时,为什么graphql java会查询实体中的所有字段?
【发布时间】:2020-07-01 20:41:14
【问题描述】:

我使用 spring boot starter 创建了一个基本的 graphql-java 应用程序,并针对 MSSQL 数据库使用 graphql spqr 利用 HibernateJpa

我有一个名为“任务”的实体,有 5 个字段。我有一个简单的 Jpa 存储库和一个调用“findAllTask​​s”方法的简单 Jpa 服务。它工作得很好,但是如果我指定,例如,只用 graphiql 查询一个字段,我可以通过我的 SQL 日志看到执行的 select 命令正在查询我的任务实体/表中的所有字段,而不是我想要的.这是预期的吗?我以为graphql只选择你在查询命令中指定的字段?

这是我的代码:

实体

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Task {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long id;

    @Column
    public String desc;

    @Column
    public LocalDateTime createdOn;

    @Column
    public LocalDateTime modifiedOn;

    @Column
    public String owner;
}

存储库

@Repository
public interface TaskRepository extends JpaRepository<Task, Long> {}

服务

@GraphQLApi
@Service
public class TaskService {
    private TaskRepository taskRepo;

    @Autowired
    public TaskService(TaskRepository taskRepo) {
        this.taskRepo = taskRepo;
    }

    @GraphQLQuery
    public List<Task> findAllTasks() {
        return taskRepo.findAll();
    }
}

当我在 graphiql 中运行以下命令时:

query {
    findAllTasks {
        id
    }
}

我得到以下从我的日志生成的 SQL 语句:

select task0_.id as Task1_1_0_. task0_.desc as Task1_2_0, task0_.createdOn as Task1_3_0, task0_.modifiedOn as Task1_4_0, task0_.owner as Task1_4_0 from Task as task0_

【问题讨论】:

    标签: graphql graphql-java graphql-spqr graphql-spring-boot


    【解决方案1】:

    您必须区分 GraphQL API 和数据库。您定义了一个名为 findAllTasks 的查询方法 GraphQL。因此,当您使用任意数量的字段调用此 GraphQL 查询时,它将调用 Java 方法实现 findAllTasks

    可以看到这个Java方法的实现调用了taskRepo.findAll()。因此,您将从数据库中的任务中获取所有数据。

    GraphQL 然后会从您的 Java 方法获取的任务中过滤数据,以匹配 GraphQL 查询中询问的内容。

    简而言之,GraphQL 只负责返回您请求的字段,但您的实现负责从数据库中获取数据。

    免责声明:我不是 graphql-spqr 专家,因此接下来的信息可能不适用于您的情况(因为它适用于 graphql- java).

    如果您觉得您的实现不够高效(这里我们真正谈论的是效率),您可以查看dataloaders

    【讨论】:

    • 感谢您的回复!这就说得通了。我猜这个问题会单独存在于 graphql-java 和 spqr 中。就像您说的那样,这似乎是 hibernate/JPA 从我的 Java 代码中的实现中获取数据的方式,这是有道理的。我对数据加载器了解不多,但我一定会去看看。
    猜你喜欢
    • 2020-11-18
    • 2020-03-23
    • 1970-01-01
    • 2018-01-12
    • 1970-01-01
    • 2018-08-02
    • 2018-08-17
    • 1970-01-01
    • 2018-09-17
    相关资源
    最近更新 更多