grahql操作
一次查询可以查询多次数据,先查询当前here的id,得到id之后,再去查向这个人的朋友
查询电影jedi和EMPIRE中英雄的名字
但是上面查询的的时候存在hero这个字段命名冲突的问题,我们可以给字段设置别名
我们也可以给name字段重命名
给query设置名字
我们查询某部电影里面hero英雄的名字和英雄朋友的信息,这里要传入电影的名称,我们定义了一个变量,变量以$开始,:是变量的类型这里是一个枚举类型
!表示这个变量必须存在,=是变量的默认值
我们修改数据用的是下面的结构
修改对象使用的是mutation关键字,修改对象的名字是createReview,函数里面需要提交两个参数一个是episode,一个是revied对象
创建之后函数createReview会有一个返回对象,对象中包含了episode和stras两个值
我们来看下查询hreo的定义
hero查询需要输入一个参数episode,参数的类型是一个枚举的Episode,hero查询的返回值是Character类型
Character是一个接口类型
human实现了Character这个接口类型
所以我们在查询的时候,一定要注意,human实现了Character的接口,human中就包含了chaaacter的所有字段,此外human还可以单独定义其他字段如appearsIl这个这段
因为hero查询默认是Character类型,所以字段必须是Character,如果要查询appearsIn,需要使用下面的形式
接下来我们看下面的search函数
参数是一个text类型,返回值是SearchResult是一个枚举类型,查询我们可以使用下面的方法
接下来看看schema
在shema中定义了一个hello的查询方法,方法的返回值是string类型
方法的resolver在root中定义
上面查询的hello和accountName方法返回值都是一个字符串类型,如果要返回一个自定义的类型,如何实现了
方法account返回值就是一个自定义的类型Account,我们需要在schema中进行定义
我们在resolver中定义如下
查询如下
我们来看下下面的这个案例
我们在shema中进行定义
resolver中进行实现
这个视频超级经典呀
https://blog.csdn.net/gaoyib6/article/details/76088903?utm_medium=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&depth_1-utm_source=distribute.pc_relevant.none-task-blog-BlogCommendFromMachineLearnPai2-1.control
我们来看下我们的案例及其使用的效果图
删除书籍
插入作者
别名的使用
2.片段
片段使你能够组织一组字段,然后在需要它们的的地方引入
3.操作名称
操作类型可以是 query、mutation 或 subscription,描述你打算做什么类型的操作。操作类型是必需的,除非你使用查询简写语法,在这种情况下,你无法为操作提供名称或变量定义。
操作名称是你的操作的有意义和明确的名称。它仅在有多个操作的文档中是必需的,但我们鼓励使用它,因为它对于调试和服务器端日志记录非常有用。
下面的示例包含了作为操作类型的关键字 query
以及操作名称 getAuhtor:
上面的查询默认我们没有写操作类型,但是我们最好按照下面的方式来编写
4.变量
所有声明的变量都必须是标量、枚举型或者输入对象类型。所以如果想要传递一个复杂对象到一个字段上,你必须知道服务器上其匹配的类型。可以从Schema页面了解更多关于输入对象类型的信息。
对于输入的变量我们也可以设置默认值
5.指令
一个指令可以附着在字段或者片段包含的字段上,然后以任何服务端期待的方式来改变查询的执行。GraphQL 的核心规范包含两个指令,其必须被任何规范兼容的 GraphQL 服务器实现所支持:
@include(if: Boolean)
仅在参数为true
时,包含此字段。@skip(if: Boolean)
如果参数为true
,跳过此字段。
指令在你不得不通过字符串操作来增减查询的字段时解救你。服务端实现也可以定义新的指令来添加新的特性。
我们来看下面的案例
指令在你不得不通过字符串操作来增减查询的字段时解救你。服务端实现也可以定义新的指令来添加新的特性。
6枚举类型
枚举类型是一种特殊的标量,它限制在一个特殊的可选值集合内。这让你能够:
- 验证这个类型的任何参数是可选值的的某一个
- 与类型系统沟通,一个字段总是一个有限值集合的其中一个值。
建立一个枚举类:
接下来我们来看看我们的代码
springboot集成grahqp:代码仓库的地址位于https://gitee.com/kebibuluan/springboot-grahql
本代码转载自:https://my.oschina.net/hanchao/blog/3014116
https://github.com/windhan2100/graphql
https://www.cnblogs.com/dionysun/p/12130440.html
https://blog.csdn.net/weixin_34356555/article/details/91893706
相当的经典呀
在spring-boot中使用graphql
首先构建spring-boot项目,pom.xml文件中加入
<dependency> <groupId>com.graphql-java-kickstart</groupId> <artifactId>graphql-java-tools</artifactId> <version>5.4.0</version> </dependency> <!-- graphql --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-spring-boot-starter</artifactId> <version>5.0.2</version> </dependency> <!-- 这个是graphiql,跟上面的不一样 --> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphiql-spring-boot-starter</artifactId> <version>5.0.2</version> </dependency>
接着定义graphql的schema,在resources目录下任意位置的*.graphqls文件都会被扫描到,作为graphql 的schema。
这里在resources下先建一个文件夹/graphql,建立schema文件
root.graphqls
#查询入口 type Query { ####### Author相关 ######### findAuthorById(id:Long!): Author findAllAuthors: [Author]! countAuthors: Long! ####### Book相关 ######### findAllBooks: [Book]! countBooks: Long! } type Mutation { newAuthor(firstName: String!,lastName: String!) : Author! newBook(title: String!,isbn: String!,pageCount: Int, authorId: Long!) : Book! saveBook(input: BookInput!) : Book! deleteBook(id: ID!) : Boolean updateBookPageCount(pageCount: Int!, id:Long!) : Book! }
schema.graphqls
type Author { #作者Id id: Long! #创建时间 createdTime: String #名 firstName: String #姓 lastName: String #该作者的所有书籍 books: [Book] } input BookInput { title: String! isbn: String! pageCount: Int authorId: Long } type Book { id: Long! title: String! isbn: String! pageCount: Int author: Author }
GraphQL Java Tools可以将schema中定义的类型的属性与java对象的属性或方法对应起来。即上面的User类型,可以使用一个类与之对应
列如schema.graphqls中定义了一个Book类
type Book { id: Long! title: String! isbn: String! pageCount: Int author: Author }
GraphQL Java Tools可以将schema中定义的类型的属性与java对象的属性或方法对应起来
package com.hanchao.graphql.graphql.entity; import lombok.Data; import lombok.EqualsAndHashCode; import javax.persistence.Column; import javax.persistence.Entity; @Entity @Data @EqualsAndHashCode(callSuper = false) public class Book extends BaseEntity { @Column(columnDefinition = "varchar(50)") private String title; private String isbn; private int pageCount; private long authorId; private Double price; }
这里我们一定要注意,GraphQL Java Tools可以将schema中定义的类型的属性与java对象的属性或方法对应起来,映射的规则如下
Type Query 没有对应的java class,如果type 中的所有字段和java class成员变量一致,则该type可以不用定义Resolver.
graphql type中的字段映射Java class字段的优先级
对于graphql objectType中的字段映射为java class字段顺序如下:
method (*fieldArgs [, DataFetchingEnvironment])
method is(*fieldArgs [, DataFetchingEnvironment]), only if the field returns a Boolean
method get(*fieldArgs [, DataFetchingEnvironment])
method getField(*fieldArgs [, DataFetchingEnvironment])
field
例如:
上述type Book中的name字段的映射顺序为:
在java Book类中找name(参数)方法。
如果Book类中没有name(参数)方法,则继续找isName(参数)方法。
如果Book中没有isName(参数)方法,则继续在Book中找getName(参数)方法。
如果Book中没有getName()方法,则继续在Book中找getFieldName(参数)方法。
如果Book中没有getFieldName(参数)方法,在继续在Book中找name成员变量。
如果Book中没有name成员变量,则报错。
graphql type中的字段映射Resolver的优先级:
method (dataClassInstance, *fieldArgs [, DataFetchingEnvironment])
method is(dataClassInstance, *fieldArgs [, DataFetchingEnvironment]), only if the field returns a Boolean
method get(dataClassInstance, *fieldArgs [, DataFetchingEnvironment])
method getField(dataClassInstance, *fieldArgs [, DataFetchingEnvironment])
注:Resolver的映射优先级高于Java Class,首先在Resolver中查找,如果没找到,才会在Java class中查找 :例如上述type Book中的author字段,会首先映射为BookResolver重的author(Book)方法。
type Book {
id: Long!
title: String!
isbn: String!
pageCount: Int
author: Author
}
type Book 中定义的id字段与Book类中name属性为id的一一对应
但是在type Book 中定义的author字段,在Book类中没有对应的字段与之对于,这个时候就要使用Resolver来解决这个问题
package com.hanchao.graphql.graphql.resolver; import com.coxautodev.graphql.tools.GraphQLResolver; import com.hanchao.graphql.graphql.entity.Author; import com.hanchao.graphql.graphql.entity.Book; import com.hanchao.graphql.graphql.enums.CountryEnum; import com.hanchao.graphql.graphql.repo.AuthorRepo; import lombok.AllArgsConstructor; import org.springframework.stereotype.Component; /** * @author hanliwei * @create 2019-02-12 17:36 */ @Component @AllArgsConstructor public class BookResolver implements GraphQLResolver<Book> { private AuthorRepo authorRepo; public Author getAuthor(Book book) { return authorRepo.findAuthorById(book.getAuthorId()); } public String getMoney(Book book,CountryEnum country) { if (country == CountryEnum.CHINA) { return "¥:" + book.getPrice() * 6; } else if (country == CountryEnum.USA) { return "$:" + book.getPrice(); } else { return "free"; } } }
项目启动的时候会查询BookResolver,发现method getField(dataClassInstance, *fieldArgs [, DataFetchingEnvironment])
getAuthor(Book book)就是安装上面的方式定义的,就会将author: Author与对应的java 的实体类关联起来
type Book {
id: Long!
title: String!
isbn: String!
pageCount: Int
author: Author
}
那么到底type Article {...}schema里面的属性怎么解析呢?是与数据类进行映射,还是与resolver中的方法进行映射?
官网上给出了映射的优先级:
首先是resolver
- method 属性名(...)
- method is属性名(...)
- method get属性名(...)
- method getField属性名(...)
其次是Data Class(即与类型对应的java类)
- method 属性名(...)
- method is属性名(...)
- method get属性名(...)
- method getField属性名(...)
- field 属性名
所以首先在ArticleResolver中查找author的映射,找不到的属性则一致向下找到属性的java类的get方法/属性本身。
2、接下来我们来看下面的代码
另外,要给Query和Mutation至少创建一个Resolver,这样让root.graphqls中定义的查询和修改方法与对于的Resolver关联起来
package com.hanchao.graphql.graphql.resolver; import com.coxautodev.graphql.tools.GraphQLQueryResolver; import com.hanchao.graphql.graphql.entity.Author; import com.hanchao.graphql.graphql.entity.Book; import com.hanchao.graphql.graphql.entity.User; import com.hanchao.graphql.graphql.enums.CountryEnum; import com.hanchao.graphql.graphql.model.Dog; import com.hanchao.graphql.graphql.model.Fish; import com.hanchao.graphql.graphql.model.Animal; import com.hanchao.graphql.graphql.repo.AuthorRepo; import com.hanchao.graphql.graphql.repo.BookRepo; import com.hanchao.graphql.graphql.repo.UserRepo; import graphql.relay.Connection; import graphql.relay.SimpleListConnection; import graphql.schema.DataFetchingEnvironment; import lombok.AllArgsConstructor; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; /** * @author hanliwei * @create 2019-02-12 18:00 */ @Component @AllArgsConstructor public class Query implements GraphQLQueryResolver { private AuthorRepo authorRepo; private BookRepo bookRepo; private UserRepo userRepo; public Author findAuthorById(Long id) { return authorRepo.findAuthorById(id); } public List<Author> findAllAuthors() { return authorRepo.findAll(); } public Long countAuthors() { return authorRepo.count(); } public List<Book> findAllBooks() { return bookRepo.findAll(); } public Long countBooks() { return bookRepo.count(); } public Book findBookById(Long id) { return bookRepo.findBookById(id); } public String testEnum(CountryEnum country) { return country.toString(); } /** * 分页测试 * @param first * @param after * @param env * @return */ public Connection<Book> books(int first,String after,DataFetchingEnvironment env) { return new SimpleListConnection<>(bookRepo.findAll()).get(env); } /** * @descript: 测试一下接口的使用 * @auther: hanliwei * @date: 2019/3/3 18:31 * @param name * @return */ public Animal getAnimal(String name) { Dog dog = new Dog(); dog.setName(name); dog.setLegs(4); Fish fish = new Fish(); fish.setName(name); fish.setTailColor("BlueAndRead"); if ("dog".equals(name)) { return dog; } else if ("fish".equals(name)) { return fish; } return null; } /** * @descript: 返回不同类型的数据 * @auther: hanliwei * @date: 2019/3/3 20:42 * @return */ public List<Animal> animals() { Dog dog = new Dog(); dog.setName("I am Dog"); dog.setLegs(4); Fish fish = new Fish(); fish.setName("I am Fish"); fish.setTailColor("BlueAndRead"); List<Animal> list = new ArrayList<>(); list.add(dog); list.add(fish); return list; } }
Query类中定义的方法名称要和root.graphqls中定义的方法名称一致,这样启动了时候grahql-java-tools这个包能够自定的进行关联扫描起来
package com.hanchao.graphql.graphql.resolver; import com.coxautodev.graphql.tools.GraphQLMutationResolver; import com.hanchao.graphql.graphql.entity.Author; import com.hanchao.graphql.graphql.entity.Book; import com.hanchao.graphql.graphql.model.BookInput; import com.hanchao.graphql.graphql.repo.AuthorRepo; import com.hanchao.graphql.graphql.repo.BookRepo; import lombok.AllArgsConstructor; import org.springframework.stereotype.Component; /** * @author hanliwei * @create 2019-02-12 18:58 */ @Component @AllArgsConstructor public class Mutation implements GraphQLMutationResolver { private AuthorRepo authorRepo; private BookRepo bookRepo; public Author newAuthor(String firstName, String lastName) { Author author = new Author(); author.setFirstName(firstName); author.setLastName(lastName); return authorRepo.save(author); } public Book newBook(String title, String isbn, int pageCount, Long authorId) { Book book = new Book(); book.setTitle(title); book.setIsbn(isbn); book.setPageCount(pageCount); book.setAuthorId(authorId); return bookRepo.save(book); } public Book saveBook(BookInput input) { Book book = new Book(); book.setTitle(input.getTitle()); book.setIsbn(input.getIsbn()); book.setPageCount(input.getPageCount()); book.setAuthorId(input.getAuthorId()); return bookRepo.save(book); } public Boolean deleteBook(Long id) { bookRepo.deleteById(id); return true; } public Book updateBookPageCount(int pageCount,long id) { Book book = bookRepo.findBookById(id); book.setPageCount(pageCount); return bookRepo.save(book); } }
上面就是整个代码的核心原理,接下来我们来看看整个代码
代码的地址位于码云
https://gitee.com/kebibuluan/springboot-grahql
pom.xml如下
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.an</groupId> <artifactId>apollo-demo-datasource</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <project.encoding>UTF-8</project.encoding> <apollo.version>1.4.0</apollo.version> <platform.bom.version>Cairo-SR2</platform.bom.version> <spring.cloud.version>Finchley.RELEASE</spring.cloud.version> <druid-boot.version>1.1.20</druid-boot.version> </properties> <dependencyManagement> <dependencies> <!-- platform bom --> <dependency> <groupId>io.spring.platform</groupId> <artifactId>platform-bom</artifactId> <version>${platform.bom.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- spring cloud --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>${spring.cloud.version}</version> <type>pom</type> <scope>import</scope> </dependency> <!-- apollo --> <dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> <version>${apollo.version}</version> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid-boot.version}</version> </dependency> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> </dependency> <dependency> <groupId>com.ctrip.framework.apollo</groupId> <artifactId>apollo-client</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-context</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.zaxxer</groupId> <artifactId>HikariCP</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-spring-boot-starter</artifactId> <version>5.0.2</version> </dependency> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphql-java-tools</artifactId> <version>5.2.4</version> </dependency> <dependency> <groupId>com.graphql-java</groupId> <artifactId>graphiql-spring-boot-starter</artifactId> <version>5.0.2</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.6</version> </dependency> <!-- graphQL end --> <!-- MYSQL&JPA begin --> <!-- MYSQL&JPA end --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> <!-- 使编译的JDK版本一致为8 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build> </project>
底层数据量的操作使用了springboot-jpa的功能
package com.hanchao.graphql.graphql; import com.coxautodev.graphql.tools.SchemaParserDictionary; import com.hanchao.graphql.graphql.model.*; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; @SpringBootApplication public class GraphqlApplication { public static void main(String[] args) { SpringApplication.run(GraphqlApplication.class, args); } /*@Bean SchemaParserDictionary schemaParserDictionary() { return new SchemaParserDictionary() .add(CreatedUser.class) .add(ErrorContainer.class) .add(LoginPayload.class) .add(Dog.class) .add(Fish.class); }*/ }
package com.hanchao.graphql.graphql.config.mysql; import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariDataSource; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.env.Environment; import javax.sql.DataSource; /** * @author hanliwei * @create 2019-01-15 15:07 */ @Configuration public class DataSourceConfig { @Autowired private Environment env; @Bean public DataSource dataSource() { HikariConfig config = new HikariConfig(); config.setDriverClassName(env.getProperty("jdbc.driver")); config.setJdbcUrl(env.getProperty("jdbc.url")); config.setUsername(env.getProperty("jdbc.username")); config.setPassword(env.getProperty("jdbc.password")); /** * 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count) */ config.setMaximumPoolSize(20); config.setMinimumIdle(5); /** * 等待连接池分配连接的最大时长(毫秒),超过这个时长还没可用的连接则发生SQLException, 缺省:30秒 */ config.setConnectionTimeout(5 * 1000L); /** * 一个连接idle状态的最大时长(毫秒),超时则被释放(retired),缺省:10分钟 */ config.setIdleTimeout(3 * 60 * 1000L); config.addDataSourceProperty("cachePrepStmts", "true"); config.addDataSourceProperty("prepStmtCacheSize", "250"); config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); config.setConnectionTestQuery("SELECT 1"); config.setPoolName("beehive_statistic"); return new HikariDataSource(config); } }
package com.hanchao.graphql.graphql.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * Just for test * * @author hanliwei * @create 2019-02-24 9:27 */ @RestController public class HanchaoController { @GetMapping("/test") public String testSpringBoot() { return "Hello, springboot"; } }
package com.hanchao.graphql.graphql.entity; import lombok.Data; import lombok.EqualsAndHashCode; import javax.persistence.Column; import javax.persistence.Entity; @Entity @Data @EqualsAndHashCode(callSuper = false) public class Author extends BaseEntity { @Column(columnDefinition = "varchar(50)") private String firstName; @Column(columnDefinition = "varchar(50)") private String lastName; }
package com.hanchao.graphql.graphql.entity; import lombok.Data; import javax.persistence.*; import java.io.Serializable; import java.util.Date; /** * @author hanliwei * @create 2019-02-12 17:18 */ @Data @MappedSuperclass public class BaseEntity implements Serializable { /** ID */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(columnDefinition = "bigint", nullable = false) protected Long id; /** 创建时间戳 (单位:秒) */ @Column(nullable = false, updatable = false) @Temporal(TemporalType.TIMESTAMP) protected Date createdTime; /** 更新时间戳 (单位:秒) */ @Column(nullable = false) @Temporal(TemporalType.TIMESTAMP) protected Date updatedTime; public BaseEntity() { createdTime = new Date(); updatedTime = createdTime; } @PreUpdate private void doPreUpdate() { updatedTime = new Date(); } }
package com.hanchao.graphql.graphql.entity; import lombok.Data; import lombok.EqualsAndHashCode; import javax.persistence.Column; import javax.persistence.Entity; @Entity @Data @EqualsAndHashCode(callSuper = false) public class Book extends BaseEntity { @Column(columnDefinition = "varchar(50)") private String title; private String isbn; private int pageCount; private long authorId; private Double price; }
package com.hanchao.graphql.graphql.entity; import lombok.Data; import javax.persistence.*; /** * @author hanliwei * @create 2019-03-02 11:03 */ @Entity @Data public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(columnDefinition = "bigint", nullable = false) private Long id; private String name; private Integer age; private String email; private String pwd; }
package com.hanchao.graphql.graphql.enums; /** * 单位 * * @author hanliwei * @create 2019-02-24 15:02 */ public enum CountryEnum { USA,CHINA; }
package com.hanchao.graphql.graphql.model; /** * 为演示GraphQL interface创建的接口 * * @author hanliwei * @create 2019-02-20 17:26 */ public interface Animal { String getName(); }
package com.hanchao.graphql.graphql.model; import lombok.Data; /** * AuthData.java * * @author hanliwei * @create 2019-03-02 11:16 */ @Data public class AuthData { private String pwd; private String email; }
package com.hanchao.graphql.graphql.model; import lombok.Data; @Data public class BookInput { private String title; private String isbn; private int pageCount; private long authorId; }
package com.hanchao.graphql.graphql.model; import com.hanchao.graphql.graphql.entity.User; import lombok.AllArgsConstructor; import lombok.Data; /** * CreatedUser.java * * @author hanliwei * @create 2019-03-02 11:14 */ @Data @AllArgsConstructor public class CreatedUser implements CreateUserResult { private User user; }
package com.hanchao.graphql.graphql.model; /** * union CreateUserResult * * @author hanliwei * @create 2019-03-02 11:13 */ public interface CreateUserResult { }
package com.hanchao.graphql.graphql.model; import lombok.Data; /** * 为演示GraphQL interface创建的实现实体 * * @author hanliwei * @create 2019-02-20 17:27 */ @Data public class Dog implements Animal { private String name; private int legs; }
package com.hanchao.graphql.graphql.model; import lombok.AllArgsConstructor; import lombok.Data; import java.util.List; /** * ErrorContainer.java * * @author hanliwei * @create 2019-03-02 11:15 */ @Data @AllArgsConstructor public class ErrorContainer implements CreateUserResult,LoginResult { private List<String> messages; }
package com.hanchao.graphql.graphql.model; import lombok.Data; /** * 为演示GraphQL interface创建的实现实体 * * @author hanliwei * @create 2019-02-20 17:29 */ @Data public class Fish implements Animal { private String tailColor; private String name; }
package com.hanchao.graphql.graphql.model; import com.hanchao.graphql.graphql.entity.User; import lombok.AllArgsConstructor; import lombok.Data; /** * @author hanliwei * @create 2019-03-02 16:00 */ @Data @AllArgsConstructor public class LoginPayload implements LoginResult{ private Long token; private User user; }
package com.hanchao.graphql.graphql.model; /** * @author hanliwei * @create 2019-03-02 16:00 */ public interface LoginResult { }
package com.hanchao.graphql.graphql.repo; import com.hanchao.graphql.graphql.entity.Author; import org.springframework.data.jpa.repository.JpaRepository; /** * @author hanliwei * @create 2019-02-12 17:29 */ public interface AuthorRepo extends JpaRepository<Author,Long> { Author findAuthorById(Long id); }
package com.hanchao.graphql.graphql.repo; import com.hanchao.graphql.graphql.entity.Book; import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; /** * @author hanliwei * @create 2019-02-12 17:31 */ public interface BookRepo extends JpaRepository<Book,Long> { List<Book> findByAuthorId(Long id); Book findBookById(Long id); }
package com.hanchao.graphql.graphql.repo; import com.hanchao.graphql.graphql.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; import java.util.List; /** * @author hanliwei * @create 2019-03-02 11:18 */ public interface UserRepo extends JpaRepository<User,Long> { /** * @descript: 通过用户名查找用户 * @auther: hanliwei * @date: 2019/3/2 11:29 * @param name 用户名 * @return User */ User findUserByName(String name); User findUserByEmail(String email); User findUserByEmailAndPwd(String email,String pwd); }
package com.hanchao.graphql.graphql.resolver; import com.coxautodev.graphql.tools.GraphQLResolver; import com.hanchao.graphql.graphql.entity.Author; import com.hanchao.graphql.graphql.entity.Book; import com.hanchao.graphql.graphql.repo.BookRepo; import lombok.AllArgsConstructor; import org.springframework.stereotype.Component; import java.text.SimpleDateFormat; import java.util.List; /** * @author hanliwei * @create 2019-02-12 17:33 */ @Component @AllArgsConstructor public class AuthorResolver implements GraphQLResolver<Author> { private static final SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); private BookRepo bookRepo; public String getCreatedTime(Author author) { return sdf.format(author.getCreatedTime()); } public List<Book> getBooks(Author author) { return bookRepo.findByAuthorId(author.getId()); } }
package com.hanchao.graphql.graphql.resolver; import com.coxautodev.graphql.tools.GraphQLResolver; import com.hanchao.graphql.graphql.entity.Author; import com.hanchao.graphql.graphql.entity.Book; import com.hanchao.graphql.graphql.enums.CountryEnum; import com.hanchao.graphql.graphql.repo.AuthorRepo; import lombok.AllArgsConstructor; import org.springframework.stereotype.Component; /** * @author hanliwei * @create 2019-02-12 17:36 */ @Component @AllArgsConstructor public class BookResolver implements GraphQLResolver<Book> { private AuthorRepo authorRepo; public Author getAuthor(Book book) { return authorRepo.findAuthorById(book.getAuthorId()); } public String getMoney(Book book,CountryEnum country) { if (country == CountryEnum.CHINA) { return "¥:" + book.getPrice() * 6; } else if (country == CountryEnum.USA) { return "$:" + book.getPrice(); } else { return "free"; } } }
package com.hanchao.graphql.graphql.resolver; import com.coxautodev.graphql.tools.GraphQLMutationResolver; import com.hanchao.graphql.graphql.entity.Author; import com.hanchao.graphql.graphql.entity.Book; import com.hanchao.graphql.graphql.model.BookInput; import com.hanchao.graphql.graphql.repo.AuthorRepo; import com.hanchao.graphql.graphql.repo.BookRepo; import lombok.AllArgsConstructor; import org.springframework.stereotype.Component; /** * @author hanliwei * @create 2019-02-12 18:58 */ @Component @AllArgsConstructor public class Mutation implements GraphQLMutationResolver { private AuthorRepo authorRepo; private BookRepo bookRepo; public Author newAuthor(String firstName, String lastName) { Author author = new Author(); author.setFirstName(firstName); author.setLastName(lastName); return authorRepo.save(author); } public Book newBook(String title, String isbn, int pageCount, Long authorId) { Book book = new Book(); book.setTitle(title); book.setIsbn(isbn); book.setPageCount(pageCount); book.setAuthorId(authorId); return bookRepo.save(book); } public Book saveBook(BookInput input) { Book book = new Book(); book.setTitle(input.getTitle()); book.setIsbn(input.getIsbn()); book.setPageCount(input.getPageCount()); book.setAuthorId(input.getAuthorId()); return bookRepo.save(book); } public Boolean deleteBook(Long id) { bookRepo.deleteById(id); return true; } public Book updateBookPageCount(int pageCount,long id) { Book book = bookRepo.findBookById(id); book.setPageCount(pageCount); return bookRepo.save(book); } }
package com.hanchao.graphql.graphql.utils; import graphql.schema.DataFetchingEnvironment; import graphql.servlet.GraphQLContext; import java.util.Optional; /** * @author hanliwei * @create 2019-03-02 16:13 */ public class Utils { public static Optional<String> getHeader(String header, DataFetchingEnvironment env) { GraphQLContext graphQLContext = env.getContext(); return graphQLContext.getHttpServletRequest() .flatMap(req -> Optional.ofNullable(req.getHeader(header))); } public static Optional<String> getAuthToken(DataFetchingEnvironment env) { Optional<String> auth = getHeader("Authorization", env); return auth.map(str -> str.replace("Bearer ", "")); } }
root.graphqls
#查询入口 type Query { ####### Author相关 ######### findAuthorById(id:Long!): Author findAllAuthors: [Author]! countAuthors: Long! ####### Book相关 ######### findAllBooks: [Book]! countBooks: Long! } type Mutation { newAuthor(firstName: String!,lastName: String!) : Author! newBook(title: String!,isbn: String!,pageCount: Int, authorId: Long!) : Book! saveBook(input: BookInput!) : Book! deleteBook(id: ID!) : Boolean updateBookPageCount(pageCount: Int!, id:Long!) : Book! }
schema.graphqls
type Author { #作者Id id: Long! #创建时间 createdTime: String #名 firstName: String #姓 lastName: String #该作者的所有书籍 books: [Book] } input BookInput { title: String! isbn: String! pageCount: Int authorId: Long } type Book { id: Long! title: String! isbn: String! pageCount: Int author: Author }
application.properties
server.port=8001 ############ mysql-å¼å§ ########### #å¯å¨æ¶ä¼æ ¹æ®å®ä½ç±»çææ°æ®è¡¨ï¼æè æ´æ°è¡¨ç»æï¼ä¸æ¸ 空æ°æ®ï¼å¼åé¶æ®µä½¿ç¨ï¼validateï¼è¡¨ç»æ稳å®å使ç¨ï¼å¯ç¨äºæ£å¼ç¯å¢ï¼ spring.jpa.hibernate.ddl-auto=update #æ§å¶å°æå°Sql spring.jpa.show-sql=true #让æ§å¶å¨è¾åºçjsonæ ¼å¼æ´ç¾è§ spring.jackson.serialization.indent-output=true #datasource jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/grahql?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull&useServerPrepStmts=true&jdbcCompliantTruncation=false jdbc.username=root jdbc.password=123456 ############ mysql-ç»æ ###########
application.yml
我们把项目启动起来,访问下面的地址就可以访问了数据库了
posted on 2020-12-08 19:57 luzhouxiaoshuai 阅读(520) 评论(0) 编辑 收藏 举报