GraphQL 学习笔记

1. 简介

GraphQL 是由 Facebook 创造的用于描述复杂数据模型的一种查询语言。这里查询语言所指的并不是常规意义上
的类似 sql 语句的查询语言,而是一种用于前后端数据查询方式的规范。
官网(中文):https://graphql.cn/
规范地址:http://spec.graphql.cn/

 

2. GraphQL解决的问题

  • 按需索取 避免浪费 (只返回需要的数据)
  • 一次查询多条数据 (多次请求的数据)

 

3. GraphQL查询的规范

see more  http://graphql.cn/learn/queries/

3.1 字段

GraphQL 学习笔记_第1张图片

3.2 参数

GraphQL 学习笔记_第2张图片

3.3 别名

GraphQL 学习笔记_第3张图片

3.4 片段

GraphQL 学习笔记_第4张图片

 

4. Schema 和类型

4.1 schema定义结构

schema {  #定义查询
 query: UserQuery
}
type UserQuery { #定义查询的类型
 user(id:ID) : User #指定对象以及参数类型
}
type User { #定义对象
 id:ID! # !表示该属性是非空项
 name:String
 age:Int
}

4.2 标准类型

  • Int :有符号 32 位整数。
  • Float :有符号双精度浮点值。
  • String :UTF‐8 字符序列。
  • Boolean : true 或者  false 。
  • ID :ID 标量类型表示一个唯一标识符,通常用以重新获取对象或者作为缓存中的键。

4.3 枚举类型

enum Episode { #定义枚举
NEWHOPE
EMPIRE
JEDI
}
type Human {
 id: ID!
 name: String!
 appearsIn: [Episode]! #使用枚举类型
 homePlanet: String
}

4.4 接口

interface Character {  #定义接口
    id: ID!
    name: String!
    friends: [Character]
    appearsIn: [Episode]!
}
#实现接口
type Human implements Character {
    id: ID!
    name: String!
    friends: [Character]
    appearsIn: [Episode]!
    starships: [Starship]
    totalCredits: Int
}
type Droid implements Character {
    id: ID!
    name: String!
    friends: [Character]
    appearsIn: [Episode]!
    primaryFunction: String
}

 

5. GraphQL Java

官网:https://www.graphql-java.com/
github:https://github.com/graphql-java/graphql-java

 


6. Java操作 GraphQL

 

6.1 依赖


  com.graphql-java
  graphql-java
  11.0

备注: graphql-java包并没有发布到maven中央仓库,需要配置第三方仓库才能使用 在setting.xml配置


 bintray
 
  
   bintray
   http://dl.bintray.com/andimarek/graphql-java
   
    true
   
   
    false
   
  
 
 
  
   bintray
   http://dl.bintray.com/andimarek/graphql-java
   
    true
   
   
    false
   
  
 

 

  bintray
 

 

6.2 创建model

public class User {

  private Long id;
  private String name;
  private Integer age;
    
   /** setter/getter **/
}

 

6.3 编写查询User对象实现

package com.sun.demo;

import com.sun.model.User;
import graphql.ExecutionResult;
import graphql.GraphQL;
import graphql.Scalars;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLObjectType;
import graphql.schema.GraphQLSchema;
import graphql.schema.StaticDataFetcher;

/**
 * @author sun
 * @version 1.0
 * @wechat 1444324903
 */
public class GraphQLDemo {

    public static void main(String[] args) {

        // 定义对象  type User{id,name}
        GraphQLObjectType userType = GraphQLObjectType.newObject()
                .name("User")
                .field(GraphQLFieldDefinition.newFieldDefinition().name("id").type(Scalars.GraphQLLong))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("name").type(Scalars.GraphQLString))
                .field(GraphQLFieldDefinition.newFieldDefinition().name("age").type(Scalars.GraphQLInt))
                .build();

        // 定义 query中的 字段
        GraphQLFieldDefinition user = GraphQLFieldDefinition.newFieldDefinition()
                .name("user")
                .type(userType)
                .dataFetcher(new StaticDataFetcher(new User(1L,"张三",20)))
                .build();

        // 定义查询的类型
        GraphQLObjectType userQuery = GraphQLObjectType.newObject()
                .name("UserQuery")
                .field(user)
                .build();

        // 定义schema
        GraphQLSchema graphQLSchema = GraphQLSchema.newSchema().query(userQuery).build();


        GraphQL graphQL = GraphQL.newGraphQL(graphQLSchema).build();

        ExecutionResult result = graphQL.execute("{user{id,age,name}}");

        System.out.println(result.getErrors());
        System.out.println(result.getData());

    }

}

 

自行测试...

 

6.4 设置查询参数

修改createUserDefinition()方法

/**
  * 定义查询的类型
  * 

  * type UserQuery { #定义查询的类型   *   user : User #指定对象   * }   *   * @return   */   public static GraphQLFieldDefinition createUserDefinition(GraphQLObjectType userType) {     return newFieldDefinition()        .name("User")        .type(userType)         //静态数据 //        .dataFetcher(new StaticDataFetcher(new User(1L, "张三", 20)))         // 设置参数        .argument(newArgument().name("id").type(GraphQLLong).build())        .dataFetcher(environment -> {           Long id = environment.getArgument("id");           return new User(id, "张三_"+id, 20 + id.intValue());        })        .build();  }

自行测试...

 

6.5 使用SDL构建schema

创建user.graphqls文件

# 在resources目录下创建user.graphqls文件

schema {
 query: UserQuery
}
type UserQuery {
 user(id:Long) : User
}
type User {
 id:Long!
 name:String
 age:Int
}

idea 安装GraphQL插件

到idea的setting -> Plugins -> search "graphql" -> install -> apply

 

6.6 构建schema

import graphql.ExecutionResult;
import graphql.GraphQL;
import graphql.schema.GraphQLSchema;
import graphql.schema.idl.RuntimeWiring;
import graphql.schema.idl.SchemaGenerator;
import graphql.schema.idl.SchemaParser;
import graphql.schema.idl.TypeDefinitionRegistry;
import org.apache.commons.io.IOUtils;
import javax.smartcardio.Card;
import java.io.IOException;
import java.util.List;
public class GraphQLSDLDemo {
  /**
  * 定义Schema
  * 

  * schema { #定义查询   *   query: UserQuery   * }   *   * @return   */   public static GraphQLSchema createGraphqlSchema(TypeDefinitionRegistry typeRegistry, RuntimeWiring wiring) {     SchemaGenerator schemaGenerator = new SchemaGenerator();     return schemaGenerator.makeExecutableSchema(typeRegistry, wiring);  }   /**   * 定义类型的注册器   *   * @param fileContent   * @return   */   public static TypeDefinitionRegistry createTypeDefinitionRegistry(String fileContent){     SchemaParser schemaParser = new SchemaParser();     return schemaParser.parse(fileContent);  }   /**   * 读取文件内容   *   * @param fileName   * @return   */   public static String readFileToString(String fileName){     try {       return IOUtils.toString(GraphQLSDLDemo.class.getClassLoader().getResourceAsStream(fileName ), "UTF-8");  } catch (IOException e) {       e.printStackTrace();    }     return null;  }   public static RuntimeWiring createRuntimeWiring() {     return RuntimeWiring.newRuntimeWiring()        .type("UserQuery", typeWiring -> typeWiring            .dataFetcher("user", environment -> {               Long id = environment.getArgument("id");               return new User(id, "张三_"+id, 20 + id.intValue());            })        ).build();  }   public static void main(String[] args) {     String fileName = "user.graphqls";     TypeDefinitionRegistry registry = createTypeDefinitionRegistry(readFileToString(fileName));     RuntimeWiring runtimeWiring = createRuntimeWiring();     GraphQL graphQL = GraphQL.newGraphQL(createGraphqlSchema(registry, runtimeWiring)).build();     // 注意:查询语句中的user是小写,要和user.graphqls文件中的属性名一致     String query = "{user(id:1){id,name,age}}";     ExecutionResult executionResult = graphQL.execute(query);     System.out.println("查询字符串:" + query);     // 打印错误     System.out.println("错误:" + executionResult.getErrors());     // 打印数据     System.out.println("结果:" +(Object) executionResult.getData());  } }

请自行测试...

 

6.7 对象嵌套

new  Card Object (1 to 1)

@Data
public class Card {

  private String cardNumber;
  private Long userId;
}

modify user object

public class User {
  private Long id;
  private String name;
  private Integer age;

  // add card obj field
  private Card card;

}|

modify user.graphql file

schema {
 query: UserQuery
}
type UserQuery {
 user(id:Long) : User
}
type User {
 id:Long!
 name:String
 age:Int
 card:Card
}
type Card {
 cardNumber:String!
 userId:Long
}

modify GraphQL SDL Demo Code

public static RuntimeWiring createRuntimeWiring() {
    return RuntimeWiring.newRuntimeWiring()
       .type("UserQuery", typeWiring -> typeWiring
           .dataFetcher("user", environment -> {
              Long id = environment.getArgument("id");
              return new User(id, "张三_"+id, 20 + id.intValue(),new
Card("number_"+id, id));
           })
       ).build();
 }

please implements  association query by youself

自行测试 ...

 

你可能感兴趣的:(Java)