本文目录导读:

- 项目依赖配置 (pom.xml)
- 实体类
- Repository层
- GraphQL Schema定义
- GraphQL Resolver实现
- 应用启动类
- 配置文件
- 测试GraphQL API
- Web页面访问
- 使用Postman测试
我将为您提供一个完整的Java GraphQL案例,包括基础配置、数据模型、查询和变更操作。
项目依赖配置 (pom.xml)
<?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>com.example</groupId>
<artifactId>graphql-demo</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.14</version>
<relativePath/>
</parent>
<properties>
<java.version>11</java.version>
<graphql-java.version>20.1</graphql-java.version>
</properties>
<dependencies>
<!-- GraphQL Java -->
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>${graphql-java.version}</version>
</dependency>
<!-- GraphQL Spring Boot Starter -->
<dependency>
<groupId>com.graphql-java-kickstart</groupId>
<artifactId>graphql-spring-boot-starter</artifactId>
<version>13.0.0</version>
</dependency>
<!-- Spring Web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Data JPA -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- H2 Database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
实体类
用户实体 (User.java)
package com.example.graphql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
@Entity
@Table(name = "users")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String email;
private String fullName;
private Integer age;
private String city;
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL, orphanRemoval = true)
private List<Post> posts = new ArrayList<>();
@Column(name = "created_at")
private LocalDateTime createdAt;
@Column(name = "updated_at")
private LocalDateTime updatedAt;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
updatedAt = LocalDateTime.now();
}
@PreUpdate
protected void onUpdate() {
updatedAt = LocalDateTime.now();
}
}
帖子实体 (Post.java)
package com.example.graphql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "posts")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Post {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String title;
@Column(columnDefinition = "TEXT")
private String content;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "author_id", nullable = false)
private User author;
private Integer likes = 0;
@Column(name = "created_at")
private LocalDateTime createdAt;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
}
}
评论实体 (Comment.java)
package com.example.graphql.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "comments")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Comment {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, columnDefinition = "TEXT")
private String content;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "post_id", nullable = false)
private Post post;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "user_id", nullable = false)
private User user;
@Column(name = "created_at")
private LocalDateTime createdAt;
@PrePersist
protected void onCreate() {
createdAt = LocalDateTime.now();
}
}
Repository层
UserRepository.java
package com.example.graphql.repository;
import com.example.graphql.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
List<User> findByAgeGreaterThanEqual(int age);
List<User> findByCityIn(List<String> cities);
List<User> findByUsernameContaining(String keyword);
}
PostRepository.java
package com.example.graphql.repository;
import com.example.graphql.entity.Post;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface PostRepository extends JpaRepository<Post, Long> {
List<Post> findPostByAuthorId(Long authorId);
List<Post> findTop10ByOrderByLikesDesc();
}
CommentRepository.java
package com.example.graphql.repository;
import com.example.graphql.entity.Comment;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CommentRepository extends JpaRepository<Comment, Long> {
List<Comment> findByPostId(Long postId);
List<Comment> findByUserId(Long userId);
}
GraphQL Schema定义
schema.graphqls
type Query {
# 用户查询
getAllUsers: [User]
getUserById(id: ID!): User
getUsersByAge(age: Int!): [User]
getUsersByCity(cities: [String!]!): [User]
searchUsers(keyword: String!): [User]
# 帖子查询
getAllPosts: [Post]
getPostById(id: ID!): Post
getPostsByAuthor(authorId: ID!): [Post]
getTopPosts(limit: Int = 10): [Post]
# 评论查询
getCommentsByPost(postId: ID!): [Comment]
}
type Mutation {
# 用户操作
createUser(input: UserInput!): User
updateUser(id: ID!, input: UserUpdateInput!): User
deleteUser(id: ID!): Boolean
# 帖子操作
createPost(input: PostInput!): Post
updatePost(id: ID!, input: PostUpdateInput!): Post
deletePost(id: ID!): Boolean
# 评论操作
addComment(input: CommentInput!): Comment
deleteComment(id: ID!): Boolean
}
type User {
id: ID!
username: String!
email: String!
fullName: String
age: Int
city: String
posts: [Post]
createdAt: String
updatedAt: String
}
type Post {
id: ID! String!
content: String
author: User
likes: Int
comments: [Comment]
createdAt: String
}
type Comment {
id: ID!
content: String!
post: Post
user: User
createdAt: String
}
input UserInput {
username: String!
email: String!
fullName: String
age: Int
city: String
}
input UserUpdateInput {
username: String
email: String
fullName: String
age: Int
city: String
}
input PostInput { String!
content: String!
authorId: ID!
}
input PostUpdateInput { String
content: String
}
input CommentInput {
content: String!
postId: ID!
userId: ID!
}
GraphQL Resolver实现
QueryResolver.java
package com.example.graphql.resolver;
import com.example.graphql.entity.Post;
import com.example.graphql.entity.User;
import com.example.graphql.repository.PostRepository;
import com.example.graphql.repository.UserRepository;
import graphql.kickstart.tools.GraphQLQueryResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class QueryResolver implements GraphQLQueryResolver {
@Autowired
private UserRepository userRepository;
@Autowired
private PostRepository postRepository;
// User queries
public List<User> getAllUsers() {
return userRepository.findAll();
}
public User getUserById(Long id) {
return userRepository.findById(id).orElse(null);
}
public List<User> getUsersByAge(int age) {
return userRepository.findByAgeGreaterThanEqual(age);
}
public List<User> getUsersByCity(List<String> cities) {
return userRepository.findByCityIn(cities);
}
public List<User> searchUsers(String keyword) {
return userRepository.findByUsernameContaining(keyword);
}
// Post queries
public List<Post> getAllPosts() {
return postRepository.findAll();
}
public Post getPostById(Long id) {
return postRepository.findById(id).orElse(null);
}
public List<Post> getPostsByAuthor(Long authorId) {
return postRepository.findPostByAuthorId(authorId);
}
public List<Post> getTopPosts(int limit) {
return postRepository.findTop10ByOrderByLikesDesc();
}
}
MutationResolver.java
package com.example.graphql.resolver;
import com.example.graphql.entity.Comment;
import com.example.graphql.entity.Post;
import com.example.graphql.entity.User;
import com.example.graphql.repository.CommentRepository;
import com.example.graphql.repository.PostRepository;
import com.example.graphql.repository.UserRepository;
import graphql.kickstart.tools.GraphQLMutationResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
public class MutationResolver implements GraphQLMutationResolver {
@Autowired
private UserRepository userRepository;
@Autowired
private PostRepository postRepository;
@Autowired
private CommentRepository commentRepository;
// User mutations
@Transactional
public User createUser(String username, String email, String fullName, Integer age, String city) {
User user = new User();
user.setUsername(username);
user.setEmail(email);
user.setFullName(fullName);
user.setAge(age);
user.setCity(city);
return userRepository.save(user);
}
@Transactional
public User updateUser(Long id, String username, String email, String fullName, Integer age, String city) {
User user = userRepository.findById(id)
.orElseThrow(() -> new RuntimeException("User not found"));
if (username != null) user.setUsername(username);
if (email != null) user.setEmail(email);
if (fullName != null) user.setFullName(fullName);
if (age != null) user.setAge(age);
if (city != null) user.setCity(city);
return userRepository.save(user);
}
@Transactional
public Boolean deleteUser(Long id) {
try {
userRepository.deleteById(id);
return true;
} catch (Exception e) {
return false;
}
}
// Post mutations
@Transactional
public Post createPost(String title, String content, Long authorId) {
User author = userRepository.findById(authorId)
.orElseThrow(() -> new RuntimeException("Author not found"));
Post post = new Post();
post.setTitle(title);
post.setContent(content);
post.setAuthor(author);
return postRepository.save(post);
}
@Transactional
public Post updatePost(Long id, String title, String content) {
Post post = postRepository.findById(id)
.orElseThrow(() -> new RuntimeException("Post not found"));
if (title != null) post.setTitle(title);
if (content != null) post.setContent(content);
return postRepository.save(post);
}
@Transactional
public Boolean deletePost(Long id) {
try {
postRepository.deleteById(id);
return true;
} catch (Exception e) {
return false;
}
}
// Comment mutations
@Transactional
public Comment addComment(String content, Long postId, Long userId) {
Post post = postRepository.findById(postId)
.orElseThrow(() -> new RuntimeException("Post not found"));
User user = userRepository.findById(userId)
.orElseThrow(() -> new RuntimeException("User not found"));
Comment comment = new Comment();
comment.setContent(content);
comment.setPost(post);
comment.setUser(user);
return commentRepository.save(comment);
}
@Transactional
public Boolean deleteComment(Long id) {
try {
commentRepository.deleteById(id);
return true;
} catch (Exception e) {
return false;
}
}
}
字段级Resolver (FieldResolver.java)
package com.example.graphql.resolver;
import com.example.graphql.entity.Comment;
import com.example.graphql.entity.Post;
import com.example.graphql.entity.User;
import com.example.graphql.repository.CommentRepository;
import com.example.graphql.repository.PostRepository;
import graphql.kickstart.tools.GraphQLResolver;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class FieldResolver implements GraphQLResolver<User> {
@Autowired
private PostRepository postRepository;
// 为User类型提供posts字段解析
public List<Post> posts(User user) {
return postRepository.findPostByAuthorId(user.getId());
}
}
@Component
class PostFieldResolver implements GraphQLResolver<Post> {
@Autowired
private CommentRepository commentRepository;
// 为Post类型提供comments字段解析
public List<Comment> comments(Post post) {
return commentRepository.findByPostId(post.getId());
}
}
应用启动类
GraphqlDemoApplication.java
package com.example.graphql;
import com.example.graphql.entity.Post;
import com.example.graphql.entity.User;
import com.example.graphql.repository.PostRepository;
import com.example.graphql.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class GraphqlDemoApplication {
public static void main(String[] args) {
SpringApplication.run(GraphqlDemoApplication.class, args);
}
@Bean
CommandLineRunner initDatabase(UserRepository userRepository, PostRepository postRepository) {
return args -> {
// 示例数据
User user1 = new User();
user1.setUsername("john_doe");
user1.setEmail("john@example.com");
user1.setFullName("John Doe");
user1.setAge(30);
user1.setCity("New York");
userRepository.save(user1);
User user2 = new User();
user2.setUsername("jane_smith");
user2.setEmail("jane@example.com");
user2.setFullName("Jane Smith");
user2.setAge(25);
user2.setCity("Los Angeles");
userRepository.save(user2);
// 创建帖子
Post post1 = new Post();
post1.setTitle("Hello GraphQL!");
post1.setContent("This is my first GraphQL post.");
post1.setAuthor(user1);
postRepository.save(post1);
Post post2 = new Post();
post2.setTitle("Getting Started with GraphQL Java");
post2.setContent("GraphQL Java is a powerful tool for building APIs.");
post2.setAuthor(user2);
postRepository.save(post2);
};
}
}
配置文件
application.yml
spring:
datasource:
url: jdbc:h2:mem:graphqldb
driver-class-name: org.h2.Driver
username: sa
password:
h2:
console:
enabled: true
jpa:
hibernate:
ddl-auto: create-drop
show-sql: true
properties:
hibernate:
format_sql: true
graphql:
servlet:
mapping: /graphql
enabled: true
cors-enabled: true
tools:
schema-location-pattern: "**/*.graphqls"
server:
port: 8080
测试GraphQL API
查询所有用户
query {
getAllUsers {
id
username
email
fullName
age
city
posts {
id
title
}
}
}
创建新用户
mutation {
createUser(
username: "alice",
email: "alice@example.com",
fullName: "Alice Johnson",
age: 28,
city: "Chicago"
) {
id
username
email
createdAt
}
}
查询特定用户的帖子
query {
getUserById(id: 1) {
id
username
posts {
id
title
content
}
}
}
添加评论
mutation {
addComment(
content: "Great post!",
postId: 1,
userId: 2
) {
id
content
createdAt
user {
username
}
}
}
Web页面访问
启动应用后,可以访问以下地址:
- GraphQL Playground: http://localhost:8080/playground
- GraphQL API: http://localhost:8080/graphql
- H2 Console: http://localhost:8080/h2-console
使用Postman测试
在Postman中发送POST请求到 http://localhost:8080/graphql,请求体格式:
{
"query": "query { getAllUsers { id username email } }"
}
这个完整的案例展示了:
- ✅ GraphQL Schema定义
- ✅ 查询和变更操作
- ✅ 字段级Resolver
- ✅ Spring Boot集成
- ✅ JPA数据持久化
- ✅ 关系映射
- ✅ 完整的CRUD操作
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播