对于 AI 代理:可在 https://www.mongodb.com/zh-cn/docs/llms.txt 获取文档索引—通过在任何 URL 路径后添加 .md 可获取所有页面的 Markdown 版本。

教程:使用 Panache 和 MongoDB 构建 Quarkus 应用程序

Panache 是一个特定于 Quarkus 框架的库,可简化基于 Hibernate 的持久层的开发。它通过提供内置CRUD操作和类型安全查询来减少样板代码。

Panache 支持 Active Record 模式(将数据库操作直接嵌入到实体类中)和 Repository 模式(将数据访问逻辑分离到专用的存储库类中)。它与 Quarkus 集成,可实现快速初创企业和低内存占用。与 Hibernate Object-Relational Mapping (ORM) 和 Java Persistence API (JPA) 配合使用,Panache 可简化数据访问,同时保持代码简洁。

在本教程中,您将使用Panache构建一个 Quarkus应用程序,以在MongoDB 数据库上执行CRUD操作和聚合。该应用程序允许您添加、更新、查找和删除图书,以及按类型计数图书。

在本教程中,您将执行以下操作:

  • 验证先决条件

  • 设置项目

  • 创建数据模型

  • 创建REST API终结点

  • 测试API

1

在开始之前,请确保您具备以下内容:

  • 已配置集群的MongoDB Atlas帐户。要学习;了解如何设立Atlas 集群,请参阅MongoDB入门指南。

  • Java 21 或更高版本。要学习;了解有关安装Java的更多信息,请访问Oracle网站。

  • 您首选的 IDE。

  • 用于管理项目依赖项的 Maven。

2

创建一个文件夹来保存 Quarkus项目。进入此目录,运行以下命令,使用 Maven 创建 Quarkus项目:

mvn io.quarkus:quarkus-maven-plugin:create \ -DprojectGroupId=io.quarkus.platform \ -DprojectArtifactId=quarkus-bom \ -DclassName="com.example.BookResource" \ -Dpath="/books"

将以下依赖项添加到您的 pom.xml文件中:

<dependencies> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-arc</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-rest</artifactId> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-rest-client-jackson</artifactId> <version>3.16.2</version> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-resteasy-reactive-jackson</artifactId> <version>3.15.1</version> </dependency> <dependency> <groupId>io.rest-assured</groupId> <artifactId>rest-assured</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.quarkus</groupId> <artifactId>quarkus-mongodb-panache</artifactId> </dependency></dependencies>

通过在项目目录中运行以下命令来构建应用程序并下载依赖项:

mvn clean install
3

首先,从项目的根目录导航到 src/main/java/com/<package>。在此目录中创建 Book.java文件。在此文件中,定义 Book 类,如以下代码所示:

import io.quarkus.mongodb.panache.PanacheMongoEntity;import io.quarkus.mongodb.panache.common.MongoEntity; @MongoEntity(collection = "books")public class Book extends PanacheMongoEntity { public String title; public String author; public String genre; public int year; public Book() { }}

该类表示MongoDB集合中的图书文档,其中包含标题、作者、流派和年份字段。

4

在包目录中创建一个 BookRepository.java文件。在此文件中,定义 BookRepository 类,如以下代码所示:

import com.quarkusWithPanache.model.Book;import io.quarkus.mongodb.panache.PanacheMongoRepository;import jakarta.enterprise.context.ApplicationScoped; @ApplicationScopedpublic class BookRepository implements PanacheMongoRepository<Book> {}

下一个,在包目录中创建一个 BookResource.java文件。在此文件中,定义一个使用您在上一示例中创建的 BookRepository 接口的资源类,如以下代码所示:

import com.mongodb.client.MongoClient;import com.mongodb.client.MongoCollection;import com.quarkusWithPanache.model.Book;import com.quarkusWithPanache.repository.BookRepository; import jakarta.inject.Inject;import jakarta.ws.rs.*;import jakarta.ws.rs.core.Response;import org.bson.Document;import org.bson.types.ObjectId; import java.util.ArrayList;import java.util.List; @Path("/books")public class BookResource { @Inject BookRepository bookRepository; @Inject MongoClient mongoClient; private MongoCollection<Document> getCollection() { return mongoClient.getDatabase("test").getCollection("books"); } @Inject public BookResource(BookRepository bookRepository) { this.bookRepository = bookRepository; } // Define API endpoints here}

以下部分介绍如何为增删改查操作和聚合实现各种API终结点。您可以在上一示例中突出显示的行下方为每个终结点添加代码。

您可以通过将以下代码添加到资源类来插入一本书:

@InjectBookRepository bookRepository; @POSTpublic Response addBook(Book book) { bookRepository.persist(book); return Response.status(Response.Status.CREATED).entity(book).build();}

您可以通过将以下代码添加到资源类中来一次插入多本书:

@POST@Path("/bulk")public Response bulkAddBooks(List<Book> books) { // Prepare documents for bulk write List<Document> documents = new ArrayList<>(); for (Book book : books) { documents.add(new Document("title", book.title) .append("author", book.author) .append("genre", book.genre) .append("year", book.year)); } getCollection().insertMany(documents); return Response.status(Response.Status.CREATED).entity(books).build();}

getCollection 方法返回 com.mongodb.client.MongoCollection包中的数据库和集合名称。

您可以通过将以下代码添加到资源类检索所有书籍:

@GETpublic List<Book> getAllBooks() { return bookRepository.listAll();}

您可以通过将以下代码添加到资源类中,根据其 _id 值检索特定书籍:

@GET@Path("/{id}")public Book getBookById(@PathParam("id") String id) { return bookRepository.findById(new ObjectId(id));}

您可以通过将以下代码添加到资源类中,根据其 _id 值删除书籍:

@DELETE@Path("/{id}")public Response deleteBook(@PathParam("id") String id) { boolean deleted = bookRepository.deleteById(new ObjectId(id)); return deleted ? Response.noContent().build() : Response.status(Response.Status.NOT_FOUND).build();}

您可以通过将以下代码添加到资源类中,按图书的 _id 值更新图书:

@PUT@Path("/{id}")public Response updateBook(@PathParam("id") String id, Book book) { Book entity = bookRepository.findById(new ObjectId(id)); if (entity == null) { return Response.status(Response.Status.NOT_FOUND).build(); } entity.title = book.title; entity.author = book.author; entity.genre = book.genre; entity.year = book.year; bookRepository.update(entity); return Response.ok(entity).build();}

您可以通过将以下聚合代码添加到资源类中,按类型对图书进行计数:

@GET@Path("/aggregate/genre-count")public Response countBooksByGenre() { List<Document> pipeline = new ArrayList<>(); pipeline.add(new Document("$group", new Document("_id", "$genre") .append("count", new Document("$sum", 1)))); List<Document> result = getCollection() .aggregate(pipeline) .into(new ArrayList<>()); return Response.ok(result).build();}
5

通过从项目的根目录运行以下命令,在 http://localhost:8080 上启动应用程序:

mvn spring-boot:run

您可以通过运行以下 curl 命令来测试API终结点:

以下 curl 命令显示了如何插入一本书:

curl -X POST "http://localhost:8080/books" -H "Content-Type: application/json" -d '{ "title": "Quarkus in Action", "author": "John Doe", "genre": "Programming", "year": 2023}'

以下 curl 命令显示了如何插入多本图书:

curl -X POST http://localhost:8080/books/bulk \ -H "Content-Type: application/json" \ -d '[ { "title": "The Midnight Library", "author": "Matt Haig", "genre": "Fiction", "year": 2020 }, { "title": "Sapiens: A Brief History of Humankind", "author": "Yuval Noah Harari", "genre": "Non-Fiction", "year": 2011 } ]'

以下 curl 命令显示如何检索所有图书:

curl -X GET "http://localhost:8080/books" | jq

以下 curl 命令显示如何检索特定图书:

curl -X GET "http://localhost:8080/books/672f873b421eaa0c3e4da49f" | jq

以下 curl 命令显示如何删除图书:

curl -X DELETE "http://localhost:8080/books/673f81b65750de0757a4bbfb" | jq

以下 curl 命令展示了如何更新书籍:

curl -X PUT "http://localhost:8080/books/672f856f421eaa0c3e4da49e" \ -H "Content-Type: application/json" \ -d '{ "title": "Quarkus in Action", "author": "John Doe", "genre": "Programming", "year": 2021 }'

以下 curl 命令显示了如何按类型对图书进行计数:

curl -X GET "http://localhost:8080/books/aggregate/genre-count" | jq

提示

使用 jq 格式 JSON 输出

如前面的示例所示,使用 jq 工具格式化 API 的 JSON 输出,提高可读性。您可以按照 jq 网站上的说明安装 jq。

要查看本教程中示例的完整版本,请参阅 quarkus-panache-with-mongodb Github 存储库。

要学习有关 Panache 的更多信息,请参阅 Quarkus网站上的MongoDB with Panache 文档。