Overview
Panache 是一个特定于 Quarkus 框架的库,可简化基于 Hibernate 的持久层的开发。它通过提供内置CRUD操作和类型安全查询来减少样板代码。
Panache 支持 Active Record 模式(将数据库操作直接嵌入到实体类中)和 Repository 模式(将数据访问逻辑分离到专用的存储库类中)。它与 Quarkus 集成,可实现快速初创企业和低内存占用。与 Hibernate Object-Relational Mapping (ORM) 和 Java Persistence API (JPA) 配合使用,Panache 可简化数据访问,同时保持代码简洁。
在本教程中,您将使用Panache构建一个 Quarkus应用程序,以在MongoDB 数据库上执行CRUD操作和聚合。该应用程序允许您添加、更新、查找和删除图书,以及按类型计数图书。
Tutorial
在本教程中,您将执行以下操作:
验证先决条件
设置项目
创建数据模型
创建REST API终结点
测试API
设置项目
创建一个文件夹来保存 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创建数据模型
首先,从项目的根目录导航到 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集合中的图书文档,其中包含标题、作者、流派和年份字段。
创建REST API终结点
在包目录中创建一个 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();}Bulk insert
您可以通过将以下代码添加到资源类中来一次插入多本书:
@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查找一个文档
您可以通过将以下代码添加到资源类中,根据其 _id 值检索特定书籍:
@GET@Path("/{id}")public Book getBookById(@PathParam("id") String id) { return bookRepository.findById(new ObjectId(id));}按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();}测试API
通过从项目的根目录运行以下命令,在 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}'Bulk insert
以下 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其他资源
要查看本教程中示例的完整版本,请参阅 quarkus-panache-with-mongodb Github 存储库。
要学习有关 Panache 的更多信息,请参阅 Quarkus网站上的MongoDB with Panache 文档。