Query
功能描述
假如没有Jimmer的支持,实现GraphQL查询需要做两类工作
-
查询聚合根对象
这是开发任何数据服务都需要做的工作,无论是GraphQL服务,REST服务,甚至其他自定义协议的服务。
开发人员只需查询并返回孤单的聚合根对象即可,无需考虑这些对象的关联属性。所以,这是相对简单的开发任务。
对Spring GraphQL而言,为控制器类的的查询方法添加注解
@QueryMapping
即可。 -
查询关联属性和计算属性
这是实现GraphQL查询的主要工作量,需要考虑当前对象的所有关联,以及实施批量加载。存在一定的工作量。
其实,也可以换一种说法,正是应为服务端承担了这些责任,客户端使用起来才会感觉到自由、便捷和强大。
对Spring GraphQL而言,提供了一些用于查询关联属性的方案,比如
用Jimmer实现GraphQL查询时,开发人员只需关注于聚合根对象的查询,只需要保证这些聚合根对象具备简单标量字段即可。这是因为
提示
实体对象的所有关联属性和计算属性都会被Jimmer自动映射为GraphQL字段,无需任何开发
警告
截止到目前为止,GraphQL协议并不支持自关联属性的递归查询。
因此,无法通过GraphQL暴露类似于对象抓取器的递归查询的功能,这是目前使用GraphQL必须接受的功能牺牲。
实现GraphQL服务
1. 最简实现
- Java
- Kotlin
BookStoreService.java
package com.example.business;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;
...省略其他导入...
@Controller
public class BookStoreService {
private final JSqlClient sqlClient;
public BookStoreService(JSqlClient sqlClient) {
this.sqlClient = sqlClient;
}
@QueryMapping
public List<BookStore> bookStores(
@Argument @Nullable String name
) {
BookStoreTable table = Tables.BOOK_STORE_TABLE;
return sqlClient
.createQuery(table)
.where(table.name().ilikeIf(name))
.select(table)
.execute();
}
}
BookStoreService.kt
package com.example.business
import org.springframework.graphql.data.method.annotation.Argument
import org.springframework.graphql.data.method.annotation.QueryMapping
import org.springframework.stereotype.Controller
...省略其他导入...
@Controller
class BookStoreService(
private val sqlClient: KSqlClient
) {
@QueryMapping
fun bookStores(
@Argument name: String?
): List<BookStore> =
sqlClient
.createQuery(BookStore::class) {
where(table.name `ilike?` name)
select(table)
}
.execute()
}