User(id:Long) : User
#查询实体类二:TableResult,对应查询名称也为TableResult
UsersList(page:Int, pageSize:Int) : TableResult
#查询实体类三:IndexAdResult ,对应查询名称也为IndexAdResult
IndexAdList:IndexAdResult
#对应实体类User
type User {
id:Long!
name:String
age:Int
#对应实体类TableResult
type TableResult{
list:[User]
pagination:Pagination
#对应实体类Pagination
type Pagination{
current:Int
pageSize:Int
total:Int
#对应实体类IndexAdResult
type IndexAdResult{
# 查询类型IndexAdResult的属性为类型IndexAdResultData的集合
# 因为字段名称list对应的类型是自定类型 所以还要在其后展开 查询条件为:
# IndexAdList{
# list{
# original
# }
list:[IndexAdResultData]
#对应实体类IndexAdResultData
type IndexAdResultData{
original:String
-
存在弊端:DataFetcher增多 不好管理
-
解决方案:定义一个DataFetcher的接口 所有DataFetcher都实现该接口 然后所有该DataFetcher的实现类 都注入到GraphqlProvider中
1、MyDataFetcher(接口)
public interface MyDataFetcher {
//查询类型中实体类对应的查询名称
String fieldName();
//通过DataFetchingEnvironment 获取查询条件对象的参数值 并返回查询到的数据
Object dataFetcher(DataFetchingEnvironment environment);
2、UserDataFetcher(MyDataFetcher实现类 对应UserQuery中User对象)
//必须注入spring 才可以在spring扫描MyDataFetcher的子类时扫描到
@Component
public class UserDataFetcher implements MyDataFetcher {
@Autowired
private UserService userService;
@Override
public String fieldName() {
//返回查询名称User 然后可以通过该名称找到对应的类型
return "User";
@Override
public Object dataFetcher(DataFetchingEnvironment environment) {
//获取User查询对象的参数id
Long id = environment.getArgument("id");
return this.userService.queryUserById(id);
3、UserListDataFetcher(MyDataFetcher实现类 对应UserQuery中UsersList对象)
//必须注入spring 才可以在spring扫描MyDataFetcher的子类时扫描到
@Component
public class UserListDataFetcher implements MyDataFetcher {
@Autowired
private UserService userService;
@Override
public String fieldName() {
//返回查询名称UsersList 然后可以通过该名称找到对应的类型
return "UsersList";
@Override
public Object dataFetcher(DataFetchingEnvironment environment) {
//获取UsersList查询对象的参数page
Integer page = environment.getArgument("page");
if(null == page){
page = 1;
//获取UsersList查询对象的参数pageSize
Integer pageSize = environment.getArgument("pageSize");
if(null == pageSize){
pageSize = 5;
return this.userService.queryList(null, page, pageSize);
4、此处省略IndexAdList实体类的DataFetcher
5、GraphqlProvider(重新实现buildWiring方法)
@Component
public class GraphqlProvider {
private GraphQL graphQL;
//注入MyDataFetcher的所有实现类
@Autowired
private List<MyDataFetcher> myDataFetchers;
@Bean
private GraphQL graphQL(){
return this.graphQL;
//实现对GraphQL对象的初始化
@PostConstruct
public void init() throws FileNotFoundException {
File file = ResourceUtils.getFile("classpath:user.graphqls");
this.graphQL = GraphQL.newGraphQL(buildGraphQLSchema(file)).build();
private GraphQLSchema buildGraphQLSchema(File file) {
TypeDefinitionRegistry typeRegistry = new SchemaParser().parse(file);
return new SchemaGenerator().makeExecutableSchema(typeRegistry, buildWiring());
private RuntimeWiring buildWiring() {
return RuntimeWiring.newRuntimeWiring()
.type("UserQuery", builder -> {
//遍历myDataFetcher的所有实现类
for (MyDataFetcher myDataFetcher : myDataFetchers) {
//获取查询的名称 然后找到其对应的类型
builder.dataFetcher(myDataFetcher.fieldName(),
//调用不同的myDataFetcher实现类的dataFetcher方法 返回查询到的数据
environment -> myDataFetcher.dataFetcher(environment));
return builder;
.build();
6.使用方法和上一篇的controller相同
- GraphQL的支持动态参数
- 传统静态参数查询语法
{
实体类查询名(字段名:"参数值"){
查询字段1
查询字段2
动态参数查询写语法