5. 数据集成
Spring for GraphQL 允许您利用现有的 Spring 技术,遵循常见的 编程模型以通过 GraphQL 公开底层数据源。
本节讨论 Spring Data 的集成层,该集成层提供了一种简单的方法:
将 Querydsl 或 Query by Example 存储库调整为 ,包括
用于自动检测和 GraphQL 查询注册的选项,用于标记的存储库
跟。DataFetcher
@GraphQlRepository
5.1. 查询
Spring for GraphQL 支持使用 Querydsl 通过 Spring Data Querydsl 扩展。 Querydsl 提供了一种灵活但类型安全的方法来表示查询谓词 使用 Annotation Processors 生成元模型。
例如,将存储库声明为 :QuerydslPredicateExecutor
public interface AccountRepository extends Repository<Account, Long>,
QuerydslPredicateExecutor<Account> {
}
然后使用它来创建一个 :DataFetcher
// For single result queries
DataFetcher<Account> dataFetcher =
QuerydslDataFetcher.builder(repository).single();
// For multi-result queries
DataFetcher<Iterable<Account>> dataFetcher =
QuerydslDataFetcher.builder(repository).many();
你现在可以通过 RuntimeWiringConfigurer
注册上述内容。DataFetcher
从 GraphQL 请求参数构建 Querydsl,并且
使用它来获取数据。Spring Data 支持 JPA、
MongoDB 和 LDAP 的 LDAP。DataFetcher
Predicate
QuerydslPredicateExecutor
如果存储库为 ,则生成器将返回 或 。Spring Data 支持此功能
变体。ReactiveQuerydslPredicateExecutor
DataFetcher<Mono<Account>>
DataFetcher<Flux<Account>>
5.1.1. 构建设置
要在构建中配置 Querydsl,请遵循官方参考文档:
例如:
dependencies {
//...
annotationProcessor "com.querydsl:querydsl-apt:$querydslVersion:jpa",
'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.2.Final',
'javax.annotation:javax.annotation-api:1.3.2'
}
compileJava {
options.annotationProcessorPath = configurations.annotationProcessor
}
<dependencies>
<!-- ... -->
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl.version}</version>
<classifier>jpa</classifier>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.hibernate.javax.persistence</groupId>
<artifactId>hibernate-jpa-2.1-api</artifactId>
<version>1.0.2.Final</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
</dependencies>
<plugins>
<!-- Annotation processor configuration -->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>${apt-maven-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
webmvc-http 示例使用 Querydsl 进行 .artifactRepositories
5.1.2. 自定义
QuerydslDataFetcher
支持自定义 GraphQL 参数绑定到属性的方式
创建 Querydsl 。默认情况下,参数被绑定为 “is equal to”
每个 available 属性。要自定义它,您可以使用 builder
方法提供 .Predicate
QuerydslDataFetcher
QuerydslBinderCustomizer
存储库本身可以是 的实例。这是自动检测的
并在自动注册期间透明地应用。但是,当手动
构建 您需要使用 Builder 方法来应用它。QuerydslBinderCustomizer
QuerydslDataFetcher
QuerydslDataFetcher
支持接口和 DTO 投影以转换查询结果
在返回这些内容以进行进一步的 GraphQL 处理之前。
要了解什么是投影,请参阅 Spring Data 文档。 要了解如何在 GraphQL 中使用投影,请参阅选择集与投影。 |
要将 Spring Data 投影与 Querydsl 存储库一起使用,请创建一个投影接口
或目标 DTO 类,并通过该方法对其进行配置,以获取生成目标类型:projectAs
DataFetcher
class Account {
String name, identifier, description;
Person owner;
}
interface AccountProjection {
String getName();
String getIdentifier();
}
// For single result queries
DataFetcher<AccountProjection> dataFetcher =
QuerydslDataFetcher.builder(repository).projectAs(AccountProjection.class).single();
// For multi-result queries
DataFetcher<Iterable<AccountProjection>> dataFetcher =
QuerydslDataFetcher.builder(repository).projectAs(AccountProjection.class).many();
5.1.3. 自动注册
如果存储库带有 注释,则它会自动注册
对于尚未注册且返回类型
与存储库域类型的匹配。这包括单值和多值
查询。@GraphQlRepository
DataFetcher
默认情况下,查询返回的 GraphQL 类型的名称必须与简单名称匹配
的存储库域类型。如果需要,您可以使用 的属性 of 指定目标 GraphQL 类型名称。typeName
@GraphQlRepository
自动注册检测给定存储库是否实现
透明地通过 Builder 方法应用它。QuerydslBinderCustomizer
QuerydslDataFetcher
自动注册是通过内置的
从 获得。Boot Starters自动
检测 bean 并使用它们来初始化 with.RuntimeWiringConfigurer
QuerydslDataFetcher
@GraphQlRepository
RuntimeWiringConfigurer
自动注册不支持自定义。
如果需要,您需要使用 to build 和
通过 RuntimeWiringConfigurer
手动注册。QueryByExampleDataFetcher
DataFetcher
5.2. 按示例查询
Spring Data 支持使用 Query by Example 来获取数据。Example 查询 (QBE) 是一种简单的查询技术,不需要 you 通过特定于 store 的查询语言编写查询。
首先声明一个存储库,该存储库为:QueryByExampleExecutor
public interface AccountRepository extends Repository<Account, Long>,
QueryByExampleExecutor<Account> {
}
用于将存储库转换为 :QueryByExampleDataFetcher
DataFetcher
// For single result queries
DataFetcher<Account> dataFetcher =
QueryByExampleDataFetcher.builder(repository).single();
// For multi-result queries
DataFetcher<Iterable<Account>> dataFetcher =
QueryByExampleDataFetcher.builder(repository).many();
你现在可以通过 RuntimeWiringConfigurer
注册上述内容。DataFetcher
使用 GraphQL 参数映射来创建
repository 并使用它作为示例对象来获取数据。Spring Data 支持 JPA、MongoDB、Neo4j 和 Redis。DataFetcher
QueryByExampleDataFetcher
如果存储库为 ,则生成器将返回 或 。Spring Data 支持此功能
MongoDB、Neo4j、Redis 和 R2dbc 的变体。ReactiveQueryByExampleExecutor
DataFetcher<Mono<Account>>
DataFetcher<Flux<Account>>
5.2.2. 自定义
QueryByExampleDataFetcher
支持接口和 DTO 投影以转换查询
结果,然后再返回这些内容以供进一步的 GraphQL 处理。
要了解什么是投影,请参阅 Spring Data 文档。 要了解投影在 GraphQL 中的作用,请参阅选择集与投影。 |
要将 Spring Data 投影与 Query by Example 存储库一起使用,请创建一个投影接口
或目标 DTO 类,并通过该方法对其进行配置,以获取生成目标类型:projectAs
DataFetcher
class Account {
String name, identifier, description;
Person owner;
}
interface AccountProjection {
String getName();
String getIdentifier();
}
// For single result queries
DataFetcher<AccountProjection> dataFetcher =
QueryByExampleDataFetcher.builder(repository).projectAs(AccountProjection.class).single();
// For multi-result queries
DataFetcher<Iterable<AccountProjection>> dataFetcher =
QueryByExampleDataFetcher.builder(repository).projectAs(AccountProjection.class).many();
5.2.3. 自动注册
如果存储库带有 注释,则它会自动注册
对于尚未注册且返回类型
与存储库域类型的匹配。这包括单值和多值
查询。@GraphQlRepository
DataFetcher
默认情况下,查询返回的 GraphQL 类型的名称必须与简单名称匹配
的存储库域类型。如果需要,您可以使用 的属性 of 指定目标 GraphQL 类型名称。typeName
@GraphQlRepository
自动注册是通过内置的
从 获得。Boot Starters自动
检测 bean 并使用它们来初始化 with.RuntimeWiringConfigurer
QueryByExampleDataFetcher
@GraphQlRepository
RuntimeWiringConfigurer
自动注册不支持自定义。
如果需要,您需要使用 to build 和
通过 RuntimeWiringConfigurer
手动注册。QueryByExampleDataFetcher
DataFetcher
5.3. 选择集与投影
出现的一个常见问题是,GraphQL 选择集与 Spring Data 预测相比如何,每个选择集扮演什么角色?
简短的回答是,Spring for GraphQL 不是转换 GraphQL 的数据网关 查询直接转换为 SQL 或 JSON 查询。相反,它允许您利用现有的 Spring 技术,并且不假定 GraphQL 架构与 底层数据模型。这就是客户驱动的选择和服务器端转换的原因 的数据模型可以起到互补的作用。
为了更好地理解,请考虑 Spring Data 将域驱动 (DDD) 设计提升为 管理数据层复杂性的推荐方法。在 DDD 中,它很重要 以遵守聚合的约束。根据定义,聚合仅在以下情况下有效 load 的 聚合功能。
在 Spring Data 中,您可以选择是希望聚合按原样公开,还是 是否在将数据模型作为 GraphQL 返回之前将其应用于数据模型 结果。有时,执行前者就足够了,默认情况下,Querydsl 和 Query by Example 集成会使 GraphQL selection set 的 set 设置为 property path 提示,底层 Spring Data 模块使用 限制选择。
在其他情况下,减少甚至转换 来适应 GraphQL 架构。Spring Data 通过 Interface 支持此功能 和 DTO Projections。
接口投影定义一组固定的属性,以公开属性可能或
可能不是 ,具体取决于 Data Store 查询结果。有两种
接口投影,这两者都决定了要从底层加载哪些属性
数据来源:null
-
如果无法部分具体化聚合对象,但仍能实现封闭界面投影,则闭合界面投影会很有帮助 想要公开属性的子集。
-
开放接口投影利用 Spring 的 Comments 和 SpEL 表达式来应用轻量级 数据转换,例如串联、计算或应用静态函数 添加到属性。
@Value
DTO 投影提供了更高级别的自定义,因为您可以放置转换 代码 (code 要么在 constructor 要么 getter methods) 中。
DTO 投影从各个属性所在的查询中实现 由投影本身确定。DTO 投影通常与 full-args 一起使用 构造函数(例如 Java 记录),因此只有在所有 必填字段(或列)是数据库查询结果的一部分。