Spring Boot集成Graphql快速入门Demo

1.Graphql介绍

GraphQL 是一个用于 API 的查询语言,是一个使用基于类型系统来执行查询的服务端运行时(类型系统由你的数据定义)。GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。

优势

  1. GraphQL 速度快,并且比较稳定,GraphQL 的操作是在数据层面的,所以比较快。

  2. GraphQL 可以获取更多的资源,当查询一个数据的时候,不止是这个数据,甚至可以很快地查询到数据引用的另一个数据。GraphQL 可以在单个请求中去获取尽量多的数据,并且在弱网状态下,GraphQL 依旧表现出色。

  3. GraphQL 是单端点查询,并在此端点中去完成所有的查询。

  4. GraphQL 的可持续性非常出色,无论是新字段、还是旧字段,它都能很好地去处理,可维护性也极佳。

  5. GraphQL 具有向下兼容的特性,就算是很久很久以前的功能,GraphQL 还是能很好地去兼容它,保证旧版本的正常运行,同时又不影响新功能的加入以及整体的稳定性。这样做的好处就是,不需要去担忧版本号问题了。

  6. GraphQL 具有强类型,在 GraphQL 的查询中,一个级别对应一个强类型,这个类型充当一个字段的描述。这样的好处就是,在查询之前,可以校验出错误并提示,方便定位问题,提高性能。

  7. 自省:可以查询 GraphQL 服务器支持的类型。这为工具和客户端软件创建了一个强大的平台,可以在这些信息的基础上构建静态类型语言的代码生成、我们的应用程序框架、Relay 或 GraphiQL 等 IDE。

  8. GraphQL 支持使用者去决定服务器支持的类型。这样的好处就是,给很多使用 GraphQL 的 工具或者端建立了一个比较成熟且强大的应用平台,通过这个平台,一些框架、工具得到不断地优化提升。

劣势

  1. GraphQL 无法完成深度查询,所以无法对于未知深度的数据进行一次性查询。

  2. GraphQL 具有非常死板的响应结构,你必须遵从这个结构去查询数据,或者自己添加一个转换器来转换。

  3. GraphQL 无法进行网络级别的缓存,你必须使用另外别的办法进行持久查询。

  4. GraphQL 默认没有上传文件的功能,GraphQL 也不接收文件类型的参数,但是你可以使用 REST 的方式进行上传文件,达到上传文件的目的。

  5. GraphQL 的执行是不可预测的,因为 GraphQL 太过于灵活了。

  6. 同样的一个简单的 API,GraphQL 会表现得很复杂,所以建议简单 API 使用 RSET。

2.mysql环境搭建

参考代码仓库里面的mysql模块,这里只贴出docker-compose.yml

version: '3'
services:mysql:image: registry.cn-hangzhou.aliyuncs.com/zhengqing/mysql:5.7container_name: mysql_3306restart: unless-stopped                                   volumes:- "./mysql/my.cnf:/etc/mysql/my.cnf"- "./mysql/init-file.sql:/etc/mysql/init-file.sql"- "./mysql/data:/var/lib/mysql"
#      - "./mysql/conf.d:/etc/mysql/conf.d"- "./mysql/log/mysql/error.log:/var/log/mysql/error.log"- "./mysql/docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d" # init sql script directory -- tips: it can be excute  when `/var/lib/mysql` is emptyenvironment:                        # set environment,equals docker run -eTZ: Asia/ShanghaiLANG: en_US.UTF-8MYSQL_ROOT_PASSWORD: root         # set root passwordMYSQL_DATABASE: demo              # init database nameports:                              # port mappping- "3306:3306"

运行

docker-compose -f docker-compose.yml -p mysql5.7 up -d

初始化脚本

CREATE DATABASE IF NOT EXISTS `BOOK_API_DATA`;
USE `BOOK_API_DATA`;CREATE TABLE IF NOT EXISTS `Book` (`id` int(20) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`pageCount` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `Index_name` (`name`)) ENGINE=InnoDB AUTO_INCREMENT=235 DEFAULT CHARSET=utf8;CREATE TABLE `Author` (`id` INT(20) NOT NULL AUTO_INCREMENT,`firstName` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_general_ci',`lastName` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8_general_ci',`bookId` INT(20) NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE,UNIQUE INDEX `Index_name` (`firstName`) USING BTREE,INDEX `FK_Author_Book` (`bookId`) USING BTREE,CONSTRAINT `FK_Author_Book` FOREIGN KEY (`bookId`) REFERENCES `BOOK_API_DATA`.`Book` (`id`) ON UPDATE CASCADE ON DELETE CASCADE
)COLLATE='utf8_general_ci'
ENGINE=InnoDB
AUTO_INCREMENT=6
;INSERT INTO `Book` (`id`, `name`, `pageCount`) VALUES (1, 'the golden ticket', '255');
INSERT INTO `Book` (`id`, `name`, `pageCount`) VALUES (2, 'coding game', '300');INSERT INTO `Author` (`id`, `firstName`, `LastName`, `bookId`) VALUES (4, 'Brendon', 'Bouchard', 1);
INSERT INTO `Author` (`id`, `firstName`, `LastName`, `bookId`) VALUES (5, 'John', 'Doe', 2);

3.代码工程

 实验目标

实现一个基于graphql查询的例子

实现过程

1. 定义Schema,Schema使用GraphQL Schema Definition Language (SDL)来定义

2. 实现Resolver,Resolver函数负责从数据源中获取请求的数据

3. 配置和启动GraphQL服务器 ,要启动GraphQL服务器,你需要安装相应的依赖和配置服务器

pomxml

<?xml version="1.0" encoding="UTF-8"?>
<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"><parent><artifactId>springboot-demo</artifactId><groupId>com.et</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>GraphQL</artifactId><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><kotlin.version>1.5.0</kotlin.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.graphql-java-kickstart</groupId><artifactId>graphql-spring-boot-starter</artifactId><version>12.0.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.graphql-java-kickstart</groupId><artifactId>graphql-java-tools</artifactId><version>12.0.0</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>26.0-jre</version></dependency><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><scope>provided</scope></dependency></dependencies>
</project>

GraphQLQueryResolver

package com.et.graphql.queryresolvers;import com.et.graphql.model.Author;
import com.et.graphql.model.Book;
import com.et.graphql.repository.AuthorRepository;
import com.et.graphql.repository.BookRepository;
import graphql.kickstart.tools.GraphQLQueryResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class BookQuery implements GraphQLQueryResolver{@AutowiredBookRepository bookRepository;@AutowiredAuthorRepository authorRepository;public Iterable<Book> allBook(){return bookRepository.findAll();}public Book getBookByName(String name){return bookRepository.findBookByName(name);}public Iterable<Author> allAuthor(){return authorRepository.findAll();}}
package com.et.graphql.queryresolvers;import com.et.graphql.model.Book;
import com.et.graphql.repository.BookRepository;
import graphql.kickstart.tools.GraphQLMutationResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.util.Optional;@Component
public class BookMutation implements GraphQLMutationResolver {@AutowiredBookRepository bookRepository;public Book newBook(String name, String pageCount){Book book =  new Book();book.setName(name);book.setPageCount(pageCount);return bookRepository.save(book);}public Book deleteBook(Integer id){Book deleteBook = new Book();Optional<Book> findBook =  bookRepository.findById(id);if(findBook.isPresent()){bookRepository.delete(findBook.get());deleteBook = findBook.get();}return deleteBook;}
}
package com.et.graphql.queryresolvers;import com.et.graphql.model.Author;
import com.et.graphql.model.Book;
import com.et.graphql.repository.AuthorRepository;
import graphql.kickstart.tools.GraphQLResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class BookAuthorResolver implements GraphQLResolver<Book> {@AutowiredAuthorRepository authorRepository;public Author getAuthor(Book book){return authorRepository.findAuthorByBookId(book.getId());}
}

graphqls(/resources/graphql)

type Book {id: Intname: StringpageCount: Stringauthor: Author
}type Query {allBook: [Book]allAuthor:[Author]getBookByName(name: String): Book
}type Mutation {newBook(name: String!, pageCount: String): BookdeleteBook(id:Int!):Book
}type Author {id: IntfirstName: StringlastName: StringbookId: Int
}

model

package com.et.graphql.model;import javax.persistence.*;@Entity
@Table(name = "Author", schema = "BOOK_API_DATA")
public class Author {@Id@GeneratedValue(strategy = GenerationType.AUTO)Integer id;@Column(name = "firstname")String firstName;@Column(name = "lastname")String lastName;@Column(name = "bookid")Integer bookId;public Author(Integer id, String firstName, String lastName, Integer bookId) {this.id = id;this.firstName = firstName;this.lastName = lastName;this.bookId = bookId;}public Author() {}public Integer getId() {return id;}public String getFirstName() {return firstName;}public String getLastName() {return lastName;}public void setId(Integer id) {this.id = id;}public void setFirstName(String firstName) {this.firstName = firstName;}public void setLastName(String lastName) {this.lastName = lastName;}public Integer getBookId() {return bookId;}public void setBookId(Integer bookId) {this.bookId = bookId;}
}
package com.et.graphql.model;import javax.persistence.*;@Entity
@Table(name = "Book", schema = "BOOK_API_DATA")
public class Book {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Integer id;private String name;@Column(name = "pagecount")private String pageCount;public Book(Integer id, String name, String pageCount) {this.id = id;this.name = name;this.pageCount = pageCount;}public Book() {}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPageCount() {return pageCount;}public void setPageCount(String pageCount) {this.pageCount = pageCount;}
}

repository

package com.et.graphql.repository;import com.et.graphql.model.Author;
import org.springframework.data.repository.CrudRepository;public interface AuthorRepository extends CrudRepository<Author, Integer> {Author findAuthorByBookId(Integer bookId);
}
package com.et.graphql.repository;import com.et.graphql.model.Book;
import org.springframework.data.repository.CrudRepository;public interface BookRepository extends CrudRepository<Book, Integer> {Book findBookByName(String name);
}

DemoApplication.java

package com.et.graphql;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;@SpringBootApplication
@ComponentScan(basePackages = "com.et.graphql.queryresolvers")
public class BookAPIApplication {public static void main(String[] args) {SpringApplication.run(BookAPIApplication.class, args);}}

application.yaml

spring.jpa.hibernate.ddl-auto=none
spring.jpa.database=mysql
spring.jpa.open-in-view=true
spring.jpa.show-sql=true
server.port=8088
#logging.level.org.hibernate=DEBUG
logging.level.org.hibernate.SQL=DEBUG
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.use-new-id-generator-mappings= false# book api db"
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=root

以上只是一些关键代码,所有代码请参见下面代码仓库

代码仓库

  • https://github.com/Harries/springboot-demo

4.测试

启动spring boot应用 打开postman,调用

http://127.0.0.1:8088/graphql 输入

query {allBook{idnamepageCount}}

返回结果4e17233ae985cef2ace7a76ad62597a6.png

5.引用

  • https://www.cnblogs.com/zcqiand/p/18011513

  • http://www.liuhaihua.cn/archives/710416.html

  • https://graphql.org/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/306807.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

蓝桥杯嵌入式(G431)备赛笔记——RTC

// RTC time// 声明一个变量 rtc_tick 用于记录上次 RTC 处理的时间 u32 rtc_tick 0;// 声明结构体变量 D 用于存储 RTC 的日期信息 RTC_DateTypeDef D;// 声明结构体变量 T 用于存储 RTC 的时间信息 RTC_TimeTypeDef T;// RTC_proc 函数&#xff0c;用于处理 RTC 时间 void R…

uniapp 开发小程序如何检测到更新点击重启小程序完成更新?

官方文档&#xff1a;uni.getUpdateManager() | uni-app官网 示例代码&#xff1a; const updateManager uni.getUpdateManager();updateManager.onCheckForUpdate(function (res) {// 请求完新版本信息的回调console.log(res.hasUpdate); });updateManager.onUpdateReady(fu…

一、flask入门和视图

run启动参数 模板渲染 后端给前端页面传参 前端页面设置css from flask import Flask, render_template,jsonify# 创建flask对象 app Flask(__name__)# 视图函数 路由route app.route("/") def hello_world():# 响应&#xff0c;返回给前端的数据return "h…

MariaDB介绍和安装

MariaDB介绍和安装 文章目录 MariaDB介绍和安装1.MariaDB介绍2.MariaDB安装2.1 主机初始化2.1.1 设置网卡名和ip地址2.1.2 配置镜像源2.1.3 关闭防火墙2.1.4 禁用SELinux2.1.5 设置时区 2.2 包安装2.2.1 Rocky和CentOS 安装 MariaDB2.2.2 Ubuntu 安装 MariaDB 2.3 源码安装2.3.…

数据结构:线性表————单链表专题

&#x1f308;个人主页&#xff1a;小新_- &#x1f388;个人座右铭&#xff1a;“成功者不是从不失败的人&#xff0c;而是从不放弃的人&#xff01;”&#x1f388; &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f3c6;所属专栏&#xff1…

类和对象二

一、运算符重载 为了使自定义类型可以使用加减等运算符&#xff0c;CPP提供了一个功能叫运算符重载。 关键字&#xff1a;operator操作符 运算符重载最好定义在类对象里&#xff0c;这也可以避免访问不到私有成员的问题。 代码演示&#xff1a; 在类里定义之后&#xff0c;…

java包目录命名

包目录命名 config controller exception model common entity enums reponse request repository security service util

大数据之ClickHouse

大数据之ClickHouse 简介 ClickHouse是一种列式数据库管理系统&#xff0c;专门用于高性能数据分析和数据仓库应用。它是一个开源的数据库系统&#xff0c;最初由俄罗斯搜索引擎公司Yandex开发&#xff0c;用于满足大规模数据分析和报告的需求。 特点 开源的列式存储数据库…

2024年mathorcup(妈妈杯)数学建模C题思路-物流网络分拣中心货量预测及人员排班

# 1 赛题 C 题 物流网络分拣中心货量预测及人员排班 电商物流网络在订单履约中由多个环节组成&#xff0c;图 ’ 是一个简化的物流 网络示意图。其中&#xff0c;分拣中心作为网络的中间环节&#xff0c;需要将包裹按照不同 流向进行分拣并发往下一个场地&#xff0c;最终使包裹…

外观模式:简化复杂系统的统一接口

在面向对象的软件开发中&#xff0c;外观模式是一种常用的结构型设计模式&#xff0c;旨在为复杂的系统提供一个简化的接口。通过创建一个统一的高级接口&#xff0c;这个模式帮助客户端通过一个简单的方式与复杂的子系统交互。本文将详细介绍外观模式的定义、实现、应用场景以…

云原生(八)、Kubernetes基础(一)

K8S 基础 # 获取登录令牌 kubectl create token admin --namespace kubernetes-dashboard1、 NameSpace Kubernetes 启动时会创建四个初始名字空间 default:Kubernetes 包含这个名字空间&#xff0c;以便于你无需创建新的名字空间即可开始使用新集群。 kube-node-lease: 该…

PostgreSQL15 + PostGis + QGIS安装教程

目录 下载1、PostgreSQL安装1.1、环境变量配置 2、PostGIS安装2.1、安装插件 3、QGIS下载3.1、安装3.2、测试 下载 PostgreSQL15安装&#xff1a;下载地址 PostGIS安装&#xff1a;下载地址&#xff08;倒数第二个&#xff09; 1、PostgreSQL安装 下载安装包之后一直点下一步…

Python 全栈系列239 使用消息队列完成分布式任务

说明 在Python - 深度学习系列32 - glm2接口部署实践提到&#xff0c;通过部署本地化大模型来完成特定的任务。 由于大模型的部署依赖显卡&#xff0c;且常规量级的任务需要大量的worker支持&#xff0c;从成本考虑&#xff0c;租用算力机是比较经济的。由于任务是属于超高计…

AR地图导览小程序是怎么开发出来的?

在移动互联网时代&#xff0c;AR技术的发展为地图导览提供了全新的可能性。AR地图导览小程序结合了虚拟现实技术和地图导航功能&#xff0c;为用户提供了更加沉浸式、直观的导览体验。本文将从专业性和思考深度两个方面&#xff0c;探讨AR地图导览小程序的开发方案。 编辑搜图 …

【大语言模型】基础:如何处理文章,向量化与BoW

词袋模型&#xff08;BoW&#xff09;是自然语言处理&#xff08;NLP&#xff09;和机器学习中一种简单而广泛使用的文本表示方法。它将文本文档转换为数值特征向量&#xff0c;使得可以对文本数据执行数学和统计操作。词袋模型将文本视为无序的单词集合&#xff08;或“袋”&a…

给现有rabbitmq集群添加rabbitmq节点

现有的&#xff1a;10.2.59.216 rabbit-node1 10.2.59.217 rabbit-node2 新增 10.2.59.199 rabbit-node3 1、分别到官网下载erlang、rabbitmq安装包&#xff0c;我得版本跟现有集群保持一致。 erlang安装包&#xff1a;otp_src_22.0.tar.gz rabbitmq安装包&#xff1…

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第三套

华为海思校园招聘-芯片-数字 IC 方向 题目分享——第三套 (共9套&#xff0c;有答案和解析&#xff0c;答案非官方&#xff0c;未仔细校正&#xff0c;仅供参考&#xff09; 部分题目分享&#xff0c;完整版获取&#xff08;WX:didadidadidida313&#xff0c;加我备注&#x…

c++编程(3)——类和对象(1)、类

欢迎来到博主的专栏——c编程 博主ID&#xff1a;代码小豪 文章目录 类对象类的访问权限类的作用域 类 c最初对c语言的扩展就是增加了类的概念&#xff0c;使得c语言在原有的基础之上可以做到信息隐藏和封装。 那么我们先来讲讲“带类的c”与C语言相比有什么改进。 先讲讲类…

Golang | Leetcode Golang题解之第24题两两交换链表中的节点

题目&#xff1a; 题解&#xff1a; func swapPairs(head *ListNode) *ListNode {dummyHead : &ListNode{0, head}temp : dummyHeadfor temp.Next ! nil && temp.Next.Next ! nil {node1 : temp.Nextnode2 : temp.Next.Nexttemp.Next node2node1.Next node2.Nex…

论文阅读:Polyp-PVT: Polyp Segmentation with PyramidVision Transformers

这篇论文提出了一种名为Polyp-PVT的新型息肉分割框架&#xff0c;该框架采用金字塔视觉变换器&#xff08;Pyramid Vision Transformer, PVT&#xff09;作为编码器&#xff0c;以显式提取更强大的特征。本模型中使用到的关键技术有三个&#xff1a;渐进式特征融合、通道和空间…