1、简介 {#1简介}
Quarkus 是一个流行的 Java 框架,经过优化,可用于创建内存占用小、启动速度极快的应用。
与流行的 NoSQL 数据库 MongoDB 搭配使用时,Quarkus 为开发高性能、可扩展的应用提供了强大的工具包。
本文将带你了解如何使用 Quarkus 配置 MongoDB、实现基本的 CRUD 操作,以及如何使用 Quarkus 的 Panache(Object Document Mapper,ODM)来简化这些操作。
2、配置 {#2配置}
2.1、Maven 依赖 {#21maven-依赖}
要在 Quarkus 中使用 MongoDB,需要添加 quarkus-mongodb-client 依赖:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mongodb-client</artifactId>
<version>3.13.0</version>
</dependency>
该依赖提供了使用 MongoDB Java 客户端与 MongoDB 数据库交互的必要工具。
2.2、运行 MongoDB 数据库 {#22运行-mongodb-数据库}
本文采用 Docker 的方式运行 MongoDB,这种方式非常便捷,无需在机器上直接安装 MongoDB。
从 Docker Hub 拉取 MongoDB 镜像:
docker pull mongo:latest
启动一个新的容器:
docker run --name mongodb -d -p 27017:27017 mongo:latest
2.3、配置 MongoDB 数据库 {#23配置-mongodb-数据库}
要配置的主要属性是访问 MongoDB 的 URL。我们可以在 connection 字符串中包含几乎所有的配置。
可以为多个节点的副本集配置 MongoDB 客户端,但在我们的示例中,使用的是 localhost 上的单机节点:
quarkus.mongodb.connection-string = mongodb://localhost:27017
3、基本的 CRUD 操作 {#3基本的-crud-操作}
数据库就绪后,现在让我们使用 Quarkus 提供的默认 Mongo 客户端实现基本的 CRUD(创建、读取、更新、删除)操作。
3.1、定义实体 {#31定义实体}
定义 Article
实体,表示 MongoDB collection
中的一个文档:
public class Article {
@BsonId
public ObjectId id;
public String author;
public String title;
public String description;
// Getter / Setter 省略
}
如上,Article
类包括 id
、author
、title
和 description
字段。ObjectId
是 BSON(JSON 的二进制表示)类型,用作 MongoDB 文档的默认 ID。
@BsonId
注解将一个字段指定为 MongoDB 文档的 ID(_id
)。当注解在一个字段上时,它表示该字段应映射到 MongoDB collection 中的 _id
字段。通过这种组合,我们可以确保每个 Article
文档都有一个唯一的 ID,MongoDB 可以用它来高效地索引和检索文档。
3.2、定义 Repository {#32定义-repository}
创建 ArticleRepository
类,使用 MongoClient
对 Article
实体执行 CRUD 操作。该类将管理与 MongoDB 数据库的连接,并提供创建、读取、更新和删除 Article
文档的方法。
首先,注入 MongoClient
实例:
@Inject
MongoClient mongoClient;
通过 MongoClient
实例,我们可以与 MongoDB 数据库交互,而无需手动管理连接。
定义一个工具方法 getCollection()
,用于从 articles
数据库中获取 articles
collection:
private MongoCollection<Article> getCollection() {
return mongoClient.getDatabase("articles").getCollection("articles", Article.class);
}
现在,可以使用 getCollection()
返回的 MongoCollection
来执行基本的 CRUD 操作:
public void create(Article article) {
getCollection().insertOne(article);
}
create()
会使用 insertOne()
方法在 MongoDB collection 中插入一个新的 Article
文档:
public List<Article> listAll() {
return getCollection().find().into(new ArrayList<>());
}
listAll()
方法可从 MongoDB collection 中检索所有 Article
文档。它利用 find()
方法查询并收集所有文档。我们还可以指定要返回的集合类型。
public void update(Article article) {
getCollection().replaceOne(new org.bson.Document("_id", article.id), article);
}
update()
方法用提供的对象替换现有的 Article
文档。该方法使用 replaceOne()
查找与 _id
匹配的文档,并用新数据对其进行更新。
public void delete(String id) {
getCollection().deleteOne(new org.bson.Document("_id", new ObjectId(id)));
}
delete()
方法根据 ID 从 collection 中删除 Article
文档。该方法会构建一个与 _id
匹配的 Filter,并使用 deleteOne
删除与该 Filter 匹配的第一个文档。
3.3、定义 Resource {#33定义-resource}
为了简单,本文仅定义 Resource 和 Repository,而不实现 Service。
现在,我们需要做的就是创建 Resource、注入 Repository,并为每个操作创建一个方法:
@Path("/articles")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ArticleResource {
@Inject
ArticleRepository articleRepository;
@POST
public Response create(Article article) {
articleRepository.create(article);
return Response.status(Response.Status.CREATED).build();
}
@GET
public List<Article> listAll() {
return articleRepository.listAll();
}
@PUT
public Response update(Article updatedArticle) {
articleRepository.update(updatedArticle);
return Response.noContent().build();
}
@DELETE
@Path("/{id}")
public Response delete(@PathParam("id") String id) {
articleRepository.delete(id);
return Response.noContent().build();
}
}
3.4、测试 API {#34测试-api}
我们可以使用 curl 命令行工具来测试 API。
首先,在数据库中添加一篇新文章,使用 HTTP POST 方法将表示文章的 JSON payload 发送到 /articles
端点:
curl -X POST http://localhost:8080/articles \
-H "Content-Type: application/json" \
-d '{"author":"John Doe","title":"Introduction to Quarkus","description":"A comprehensive guide to the Quarkus framework."}'
使用 HTTP GET 方法从数据库中获取所有文章,以验证文章是否已成功存储:
curl -X GET http://localhost:8080/articles
这会返回一个 JSON 数组,其中包含当前存储在数据库中的所有文章:
[
{
"id": "66a8c65e8bd3a01e0a509f0a",
"author": "John Doe",
"title": "Introduction to Quarkus",
"description": "A comprehensive guide to Quarkus framework."
}
]
4、使用 Panache {#4使用-panache}
Quarkus 提供了一个名为 Panache 的额外抽象层,可以简化数据库操作,减少模板代码。有了 Panache,我们就可以把更多精力放在业务逻辑上,而不是数据访问代码上。
来看看如何使用 Panache 实现相同的 CRUD 操作。
4.1、Maven 依赖 {#41maven-依赖}
要在 MongoDB 中使用 Panache,需要添加 quarkus-mongodb-panache 依赖:
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-mongodb-panache</artifactId>
<version>3.13.0</version>
</dependency>
4.2、定义实体 {#42定义实体}
使用 Panache 时,实体类需要继承 PanacheMongoEntity
,它提供了用于常见数据库操作的内置方法。还要使用 @MongoEntity
注解来定义 MongoDB 集合:
@MongoEntity(collection = "articles", database = "articles")
public class Article extends PanacheMongoEntityBase {
private ObjectId id;
private String author;
private String title;
private String description;
// Getter / Setter 方法省略
}
4.3、定义 Repository {#43定义-repository}
通过实现 PanacheMongoRepository
来创建一个 Repository。这为我们提供了 CRUD 操作,而无需编写模板代码:
@ApplicationScoped
public class ArticleRepository implements PanacheMongoRepository<Article> {}
实现 PanacheMongoRepository
类,我们可以直接使用 persistence()
、listAll()
和 findById
等方法,用于执行 CRUD 操作和管理 MongoDB 实体。
4.4、定义 Resource {#44定义-resource}
现在,创建新的 Resource,使用新的 Repository:
@Path("/v2/articles")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ArticleResource {
@Inject
ArticleRepository articleRepository;
@POST
public Response create(Article article) {
articleRepository.persist(article);
return Response.status(Response.Status.CREATED).build();
}
@GET
public List<Article> listAll() {
return articleRepository.listAll();
}
@PUT
public Response update(Article updatedArticle) {
articleRepository.update(updatedArticle);
return Response.noContent().build();
}
@DELETE
@Path("/{id}")
public Response delete(@PathParam("id") String id) {
articleRepository.delete(id);
return Response.noContent().build();
}
}
4.5、测试 API {#45测试-api}
可以使用与上述示例中相同的 curl
命令来测试新的 API。唯一要改变的是调用的 endpont
,这次调用的是 /v2/articles
API。
创建新文章:
curl -X POST http://localhost:8080/v2/articles \
-H "Content-Type: application/json" \
-d '{"author":"John Doe","title":"Introduction to MongoDB","description":"A comprehensive guide to MongoDB."}'
检索所有文章:
curl -X GET http://localhost:8080/v2/articles
5、总结 {#5总结}
本文介绍了如何在 Quarkus 中整合、使用 MongoDB,以及如何使用默认的 Mongo 客户端和 Panache(ODM)来操作数据库和文档。
Ref:https://www.baeldung.com/java-quarkus-mongodb