Spring Boot整合GraphQL

RPC选型入门测试系列文章

GraphQL是一种用于API开发的查询语言和运行时环境。它由Facebook开发并于2015年开源。GraphQL的主要目标是提供一种更高效、灵活和易于使用的方式来获取和操作数据。与传统的RESTful API相比,GraphQL允许客户端精确地指定需要的数据,并减少了不必要的网络传输和数据处理。
采用GraphQL,甚至不需要有任何的接口文档,在定义了Schema之后,服务端实现Schema,客户端可以查看Schema,然后构建出自己需要的查询请求来获得自己需要的数据。

1、数据类型

1.1、标量类型
  1. Int -32位整型数字;
  2. Float-双精度浮点型;
  3. String-UTF‐8 字符序列;
  4. Boolean-布尔型,true 或者 false;
  5. ID-标识类型,唯一标识符,注意此ID为字符,如果使用Mysql自增长id,也会自动转为对应的字符串;
1.2. 高级数据类型
  1. Object - 对象,用于描述层级或者树形数据结构。Object类型有一个类型名,以及类型包含的字段。
type Product {id: ID!info: String!price: Float
}
12345

在此示例中,声明了Product对象类型,定义了3 个字段:
id:非空 ID 类型。
info:非空字符串类型。
price:浮点型。

  1. Interface-接口,用于描述多个类型的通用字;与 Object一样。
interface Product {id: ID!info: String!price: Float
}
12345
  1. Union-联合类型,用于描述某个字段能够支持的所有返回类型以及具体请求真正的返回类型;
  2. Enum-枚举,用于表示可枚举数据结构的类型;
enum Status {YesNo
}
type Product {id: ID!info: String!price: Floatstat: Status
}
12345678910
  1. Input-输入类型input本质上也是一个type类型,是作为Mutation接口的输入参数。换言之,想要定义一个修改接口(add,update,delete)的输入参数对象,就必须定义一个input输入类型。
input BookInput {isbn: ID!title: String!pages: IntauthorIdCardNo: String
}
123456
  1. List -列表,任何用方括号 ([]) 括起来的类型都会成为 List 类型。
type Product {id: ID!info: Stringprice: Floatimages: [String]
}
123456
  1. Non-Null-不能为 Null,类型后边加!表示非空类型。例如,String 是一个可为空的字符串,而String!是必需的字符串。

基本操作

  • Query(只读操作)
#schema.graphqls定义操作
type Query {allBooks: [Book]!bookByIsbn(isbn: ID): Book
}# 接口查询语法
query{allBooks {titleauthor {nameage}}
}
12345678910111213141516
  • Mutation(可写操作)
#schema.graphqls定义操作
type Mutation {createBook(bookInput: BookInput): BookcreateAuthor(authorInput: AuthorInput): Author
}# mutation{
#   createAuthor(authorInput:{ 
#     idCardNo: "341234567891234567",
#     name:"test1",
#     age:38
#   }
#   ){
#     name 
#     age
#   }
# }

2、Spring Boot整合GraphQL

GraphQL只是一种架构设计,具体的实现需要各个技术平台自己实现,目前主流的开发语言基本都已经有现成的类库可以使用,GraphQL Java就是Java平台的实现。

spring-graphql中定义的核心注解如下:

  • @GraphQlController:申明该类是GraphQL应用中的控制器
  • @QueryMapping:申明该类或方法使用GraphQL的query操作,等同于@SchemaMapping(typeName = “Query”),类似于@GetMapping
  • @Argument:申明该参数是GraphQL应用的入参
  • @MutationMapping:申明该类或方法使用GraphQL的mutation操作,等同于@SchemaMapping(typeName = “Mutation”)
  • @SubscriptionMapping:申明该类或方法使用GraphQL的subscription操作,等同于@SchemaMapping(typeName = “Subscription”)
  • @SchemaMapping:指定GraphQL操作类型的注解,类似@RequestMapping
2.1、项目目录

项目代码目录
![在这里插入图片描述](https://img-blog.csdnimg.cn/9a7b5d2461224e378ad48dca2ba0baa0.jpeg#pic_center

2.3、GraphQL的schema.graphql

GraphQL对应的schema.graphql定义文件

schema {query: Query,mutation: Mutation,
}type Query {getUserById(id:Int) : [User],
}input UserInput {username : String,password : String,name : String,
}
type Mutation {createUser(userInput: UserInput): User,updateUser(id: Int!, userInput: UserInput): User,deleteUser(id: ID!): Int,}
type User {id : ID!,username : String,password : String,name : String,
}
2.4、Java代码

pom.xml依赖包文件

	<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-graphql</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version></dependency><dependency><groupId>com.graphql-java</groupId><artifactId>graphql-java-extended-scalars</artifactId><version>19.1</version></dependency></dependencies>
</project>

对应的数据库实体类

package com.example.graphql.dao;import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private int id;private String username;private String password;private String name;public User(String username, String password, String name) {this.username = username;this.password = password;this.name = name;}
}

GraphQL对应的输入类

package com.example.graphql.dao;
import lombok.Data;
import java.time.OffsetDateTime;
@Data
public class UserInput {private String username;private String password;private String name;
}

操作数据库

在Spring Data JPA中使用JpaRepository接口类完成对数据库的操作

增加、修改

JpaRepository中,当保存的实体类主键ID在数据库中存在时进行修改操作,不存在则进行保存。

    @Autowiredprivate UserInfoRepository userInfoRepository;public void addUserInfo() {UserInfo userInfo = new UserInfo();userInfo.setId("jHfnKlsCvN");userInfo.setLoginName("登录名");userInfo.setPassword("123456");userInfo.setAge(18);// 保存或修改用户信息, 并返回用户实体类UserInfo save = userInfoRepository.save(userInfo);}
删除【根据实体类主键删除】
    @Autowiredprivate UserInfoRepository userInfoRepository;public void deleteUserInfo() {// 根据实体类主键删除userInfoRepository.deleteById("111");}
查询
查询单个信息【findBy】

JpaRepository中根据某一个字段或者某几个字段查询时,就使用findBy方法。
这里给个例子,假设,我想根据loginName查询用户信息,就可以用findByLoginName查询用户信息,如果有多个条件后面就继续拼接AndXXX
假设,我想查询loginName等于某值,并且password等于某值的,就可以使用findByLoginNameAndPassword

public interface UserInfoRepository extends JpaRepository<UserInfo, String> {// 根据登录名查询用户信息UserInfo findByLoginName(String loginName);// 根据登录名和密码查询用户信息UserInfo findByLoginNameAndPassword(String loginName, String password);
}
查询多个信息【findAllBy】

JpaRepository中根据某一个字段或者某几个字段查询时,就使用findAllBy方法,而接口根据某个条件查询写法跟查询单个信息时一样。
这里给个例子,假设,我想查询loginName等于某值的所有用户信息时,就写做findAllByLoginName

public interface UserInfoRepository extends JpaRepository<UserInfo, String> {// 查询所有登录名叫做XXX的用户List<UserInfo> findAllByLoginName(String loginName);
}
对应的数据库操作类```java
package com.example.graphql.servise.Repository;import com.example.graphql.dao.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.List;
@Service
@Repository
//必须声明事务,不然删除报错
@Transactional
public interface UserRepository extends JpaRepository<User, Long> {List<User> findById(int id);
//  List<User> updateById(int id);int deleteById(int id);}

对外服务接口类
在service层中实现查询和删除:

package com.example.graphql.servise;import com.example.graphql.dao.User;
import com.example.graphql.servise.Repository.UserRepository;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserService {@Resourceprivate UserRepository userRepository ;public List<User> queryUser(int id) {List<User> user = userRepository.findById(id);return user;}public int deleteUser(int id) {int bool = userRepository.deleteById(id);return bool;}
}

在controller层中配置增删改查接口:

package com.example.graphql.controller;import com.example.graphql.dao.User;
import com.example.graphql.dao.UserInput;
import com.example.graphql.servise.Repository.UserRepository;
import com.example.graphql.servise.UserService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.MutationMapping;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.*;import java.util.List;@RestController
@RequestMapping("/user")
@CrossOrigin
public class UserController {@Resourceprivate UserService userService;@Resourceprivate UserRepository userRepository ;@QueryMappingpublic List<User> getUserById(@Argument int id) {return userService.queryUser(id);}@MutationMappingpublic int deleteUser(@Argument int id) {return userService.deleteUser(id);}@MutationMappingpublic User createUser(@Argument UserInput userInput) {User user = new User();System.out.println(userRepository);System.out.println(user);BeanUtils.copyProperties(userInput,user);userRepository.save(user);return user;}@MutationMappingpublic User updateUser(@Argument int id,@Argument UserInput userInput) {System.out.println(userInput);User user = new User();user.setId(id);BeanUtils.copyProperties(userInput,user);System.out.println(user);userRepository.save(user);return user;}
}

3、运行效果

3.1、添加用户

在这里插入图片描述

3.2、查询用户

在这里插入图片描述

3.3、更新用户

在这里插入图片描述

3.4、删除用户

在这里插入图片描述

4、总结

使用Spring for GraphQL试用了GraphQL后,它实现按需取数据的功能。服务器开发人员和前端开发人员可以通过schema.graphqls定义文件,协定好接口和数据,省掉写接口文档的工作。
客户端可以通过一次请求获取多个数据资源,而不需要发起多个请求。相对于传统的RESTful API,GraphQL的实现和后端处理逻辑可能更加复杂。需要编写解析器、验证查询、处理复杂的字段解析和数据获取等。

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

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

相关文章

Unity中Shader裁剪空间推导(在Shader中使用)

文章目录 前言一、在Shader中使用转化矩阵1、在顶点着色器中定义转化矩阵2、用 UNITY_NEAR_CLIP_VALUE 区分平台矩阵3、定义一个枚举用于区分当前是处于什么相机 二、我们在DirectX平台下&#xff0c;看看效果1、正交相机下2、透视相机下3、最终代码 前言 在上一篇文章中&…

高光回眸:阿里云容器服务如何全面助力精彩亚运

作者&#xff1a;刘佳旭 谢乘胜 贤维 引言 2023 年&#xff0c;第 19 届杭州亚运会在杭州成功举办。在亚运之光和科技之光的交相辉映下&#xff0c;这届亚运会成为亚运史上首届“云上亚运”&#xff0c;用云计算创造了历史&#xff0c;赛事核心系统和转播全面上云&#xff0c…

[足式机器人]Part2 Dr. CAN学习笔记-自动控制原理Ch1-6根轨迹Root locus

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记-自动控制原理Ch1-6根轨迹Root locus 1. 根的作用2. 手绘技巧3. 分离点/汇合点&根轨迹的几何性质 1. 根的作用 G ( s ) s 3 s 2 2 s 4 G\left( s \right) \frac{s3}{s^22s4} G(s)s22s4s3​…

Qt Quick 用cmake怎么玩子项目

以下内容为本人的著作&#xff0c;如需要转载&#xff0c;请声明原文链接 微信公众号「ENG八戒」https://mp.weixin.qq.com/s/o-_aGqreuQda-ZmKktvxwA 以往在公司开发众多的项目中&#xff0c;都会出现要求本项目里部分功能模块代码需要具备保密性。如果需要对外输出demo工程&…

如何拍摄好VR全景图片,VR全景图片后期处理有什么技巧

引言&#xff1a; VR全景图片是一种以全景视角呈现场景的图片&#xff0c;通过VR技术可以将用户带入虚拟的环境中&#xff0c;给人一种身临其境的感觉&#xff0c;那么如何才能更好的制作让人满意的全景图片呢&#xff1f; 一&#xff0e;如何拍摄好VR全景图片 1.选择合适的拍…

vue中常见的指令

简单介绍一下常见的vue中用到的指令 v-on 指定当前的事件&#xff0c;语法糖为&#xff0c;如例子所示&#xff0c;指定按钮的事件为addCounter&#xff0c;点击会使变量counter 1 <!DOCTYPE html> <html><head><meta charset"utf-8" />…

Unity JSON编码解码之LitJson 深度剖析

把LitJson的代码库放入到项目中&#xff0c;如图所示:JSON在游戏开发中是一种序列化/反序列化常用的技术&#xff0c;把游戏相关的数据,如地图组成,通过JSON编码&#xff0c;序列化成JSON文本&#xff0c;传输或存储, 要使用的时候再通过JSON技术把文本解析成数据对象&#xff…

2023-12-29 服务器开发-centos-安装php8

摘要: 2023-12-29 服务器开发-centos-安装php8 centos-安装php8 必备条件 Minimal CentOS 8 / RHEL 8User with sudo rightsInternet Connection (1) 更新系统 更新系统 $ sudo dnf update $ sudo dnf upgrade 重启系统 $ sudo reboot (2) 启用 EPEL & Remi 软件库…

【教学类-43-03】20231229 N宫格数独3.0(n=1、2、3、4、6、8、9) (ChatGPT AI对话大师生成 回溯算法)

作品展示&#xff1a; 背景需求&#xff1a; 大4班20号说&#xff1a;我不会做这种&#xff08;九宫格&#xff09;&#xff0c;我做的是小格子的&#xff0c; 他把手工纸翻过来&#xff0c;在反面自己画了矩阵格子。向我展示&#xff1a;“我会做这种&#xff01;” 原来他会…

Android笔记(二十三):Paging3分页加载库结合Compose的实现分层数据源访问

在Android笔记&#xff08;二十二&#xff09;&#xff1a;Paging3分页加载库结合Compose的实现网络单一数据源访问一文中&#xff0c;实现了单一数据源的访问。在实际运行中&#xff0c;往往希望不是单纯地访问网络数据&#xff0c;更希望将访问的网络数据保存到移动终端的SQL…

GitHub Copilot 终极详细介绍

编写代码通常是一项乏味且耗时的任务。现代开发人员一直在寻找新的方法来提高编程的生产力、准确性和效率。 像 GitHub Copilot 这样的自动代码生成工具可以使这成为可能。 GitHub Copilot 到底是什么&#xff1f; GitHub Copilot 于 2021 年 10 月推出&#xff0c;是 GitHub 的…

【无标题】《巴黎图书馆》,又发现一本书

我喜愛看的书(https://img-blog.csdnimg.cn/8cd84d33e6724f09a46831f75abe6464.jpg)在这里插入图片描述

c语言-string.h库函数初识

目录 前言一、库函数strlen()1.1 strlen()介绍1.2 模拟实现strlen() 二、库函数strcpy()2.1 strcpy()介绍2.2 模拟实现strcpy() 三、库函数strcmp()3.1 strcmp()介绍3.3 模拟实现strcmp() 总结 前言 本篇文章介绍c语言<string.h>头文件中的库函数&#xff0c;包含strlen…

网络交换机端口管理会面临的问题

交换机端口管理是跟踪网络交换机及其端口连接详细信息的过程&#xff0c;在大型网络中&#xff0c;交换机端口管理过程通常使用自动化交换机端口管理工具执行。 通过网络交换机端口提供的完全控制和可见性使交换机端口管理工具在管理网络时必不可少&#xff0c;在网络中部署交…

权重函数设计

1e4/(0.5*s^21*s1) 1.4125 抑制驱动器饱和 1e-4*(s1)/(0.001*s1) 10*(s10)/(s1000) 1e-6*(s1)/(0.001*s1) [0.01,0.1],[0.001,1] 0.5*(0.05*s1)/(0.0001*s0.01)

Vue2 - v-model 简介

目录 1&#xff0c;原理1.1&#xff0c;作用于表单元素1.2&#xff0c;作用于自定义组件 2&#xff0c;编译结果展示2.2&#xff0c;表单元素2.1&#xff0c;自定义组件 1&#xff0c;原理 官网参考 v-model 是一个语法糖&#xff0c;最终会生成一个属性和一个事件。并且即可…

彻底理解前端安全面试题(1)—— XSS 攻击,3种XSS攻击详解,建议收藏(含源码)

前言 前端关于网络安全看似高深莫测&#xff0c;其实来来回回就那么点东西&#xff0c;我总结一下就是 3 1 4&#xff0c;3个用字母描述的【分别是 XSS、CSRF、CORS】 一个中间人攻击。当然 CORS 同源策略是为了防止攻击的安全策略&#xff0c;其他的都是网络攻击。除了这…

FFmpeg学习笔记--Centos8安装FFmpeg

1--安装指令 sudo yum install epel-releasesudo yum localinstall --nogpgcheck https://download1.rpmfusion.org/free/el/rpmfusion-free-release-8.noarch.rpmsudo yum install ffmpeg ffmpeg-develffmpeg -version 2--版本信息

【c语言】飞机大战(1)

提前准备好游戏要的素材&#xff0c;可以到爱给网去找&#xff0c;飞机大战我们需要的是一个我方战机图片&#xff0c;一个背景图&#xff0c;三个敌方战机的图&#xff0c;我方战机的图片&#xff0c;敌方战机的图片&#xff0c;并且将图片和.cpp放在同一文件夹下. 这里创建.…

如何在MAC OS中的XCODE下添加 <bits/stdc++.h>

mac上使用的编译器是Clang&#xff0c;但是没有万能头文件bits/stdc.h\&#xff0c;本文介绍如何添加万能头文件 Xcode 版本&#xff1a;15.1 - 打开应用程序-Xcode-右键显示包内容 Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/includ…