GraphQL(9):Spring Boot集成Graphql简单实例

1 安装插件

我这边使用的是IDEA,需要先按照Graphql插件,步骤如下:

(1)打开插件管理

在IDEA中,打开主菜单,选择 "File" -> "Settings" (或者使用快捷键 Ctrl + Alt + S 或 Cmd + ,),然后在弹出的对话框中选择 "Plugins"。

(2)搜索GraphQL插件

在插件管理器中,你会看到一个搜索框。在搜索框中输入 "GraphQL" 或者其他相关的关键词,然后按下回车键或者点击搜索图标。

(3)安装插件

(4)重启IDEA

安装完成以后重启IDEA

2 新建数据库

脚本如下:

复制代码
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 代码实现

下面实现一个简单的查询

3.1 引入依赖

复制代码
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-graphql</artifactId>
            <version>3.3.0</version>
        </dependency>

完整pom文件如下:

复制代码
<?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">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>springbootgraphql</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.5</version>
        <relativePath />
    </parent>

    <properties>
        <java.version>1.8</java.version>
<!--        <kotlin.version>1.1.16</kotlin.version>-->
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </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>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-graphql</artifactId>
            <version>3.3.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>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

</project>

3.2 新建实体类

新建Author实体类

复制代码
package com.example.demo.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;
    }
}

新建Book实体类

复制代码
package com.example.demo.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;
    }
}

新建输入AuthorInput实体

复制代码
package com.example.demo.model.Input;


public class AuthorInput {

    String firstName;

    String lastName;

    Integer bookId;


    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }


    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;
    }
}

3.3 新建repository类

新建AuthorRepository类

复制代码
package com.example.demo.repository;

import com.example.demo.model.Author;
import org.springframework.data.repository.CrudRepository;

public interface AuthorRepository extends CrudRepository<Author, Integer> {
    Author findAuthorByBookId(Integer bookId);
}

新建BookRepository类

复制代码
package com.example.demo.repository;

import com.example.demo.model.Book;
import org.springframework.data.repository.CrudRepository;

public interface BookRepository extends CrudRepository<Book, Integer> {

    Book findBookByName(String name);
}

3.4 新建Service层

复制代码
package com.example.demo.service;

import com.example.demo.model.Author;
import com.example.demo.repository.AuthorRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


@Service
public class AuthorSevice {
    @Autowired
    private AuthorRepository authorRepository;

    public void addAuthon(Author author) {
        authorRepository.save(author);
    }

    public Author queryAuthorByBookId(int bookid) {
        Author author = authorRepository.findAuthorByBookId(bookid);
        return author;
    }

}

3.5 新建控制器

复制代码
package com.example.demo.controller;

import com.example.demo.model.Author;
import com.example.demo.model.Input.AuthorInput;
import com.example.demo.service.AuthorSevice;
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.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.RestController;

@CrossOrigin
@RestController
public class AuthorController {
    @Autowired
    private AuthorSevice authorSevice;


    /**
     * 经典 hollo graphql
     */
    @QueryMapping
    public String hello(){
        return "hello graphql";
    }
    @QueryMapping
    public Author getAuthorBybookId(@Argument int bookid) {
        System.out.println("bookid:"+bookid);
        return authorSevice.queryAuthorByBookId(bookid);
    }


    @MutationMapping
    public Author createUser(@Argument AuthorInput authorInput) {
        Author author = new Author();
        BeanUtils.copyProperties(authorInput,author);
        authorSevice.addAuthon(author);
        return author;
    }
}

3.6 新建graphql文件

在resource文件中新建graphql文件

编写root.graphql文件

复制代码
schema {
    query: Query
    mutation: Mutation
}
type Mutation{
}
type Query{
}

编写books.graphql文件

复制代码
extend type Query {
    hello:String
    getAuthorBybookId(bookid:Int): Author
}

extend type Mutation {
    createUser(authorInput: AuthorInput):Author
}

input AuthorInput {
    firstName: String
    lastName: String
    bookId: Int
}


type Author {
    id: Int
    firstName: String
    lastName: String
    bookId: Int
}

type Book {
    id: Int
    name: String
    pageCount: String
    author: Author
}

3.7 编写yml配置文件

复制代码
spring:
  jpa:
    hibernate:
      use-new-id-generator-mappings: false
  graphql:
    graphiql:
      enabled: true
    websocket:
      path: /graphql
    schema:
      printer:
        enabled: true
      locations: classpath:/graphql   #test.graphql文件位置
      file-extensions: .graphql
  datasource:
    url: jdbc:mysql://192.168.222.156:3306/book_api_data?useUnicode=true&characterEncoding=utf-8&useSSL=false
    password: 123456
    username: root
server:
  port: 8088

3.8 编写启动类

复制代码
package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class graphqlApplication {
    public static void main(String[] args) {
        SpringApplication.run(graphqlApplication.class,args);
    }
}

4 启动测试

启动后访问http://localhost:8088/graphiql?path=/graphql&wsPath=/graphql

测试查询功能

测试新增功能

相关推荐
指令集梦境15 小时前
Cursor + Spring Boot实战:从零写一个RESTful API
spring boot·后端·restful
码云之上15 小时前
聊聊如何设计一个高效、稳定的 Node.js 接入层
前端·后端·node.js
IT_陈寒16 小时前
Vite项目build后路由404了?你可能漏了这个小配置
前端·人工智能·后端
宸津-代码粉碎机17 小时前
Spring AI企业级实战|从RAG优化到Agent多工具调度
java·大数据·人工智能·后端·python·spring
吴佳浩17 小时前
AI Infra 的真相:Go 没输,rust也不是取代
后端·rust·go
喵个咪17 小时前
实时游戏网络协议深度对比:KCP vs WebRTC vs WebSocket
后端·websocket·webrtc
普通网友17 小时前
springboot之集成Elasticsearch
spring boot·后端·elasticsearch
QuZero17 小时前
Guava Cache Deep Dive
java·后端·算法·guava
leeyi18 小时前
SSE 实时推流 —— Token 怎么一个个蹦出来
后端·agent
leeyi18 小时前
ReAct 循环的 50 行 Go 实现,逐行拆解
后端·agent