Overview
panache は、 Hibernetes ベースの永続性レイヤーの開発を簡素化する 引用符 フレームワーク固有のライブラリです。組み込みのCRUD操作と型セーフなクエリを提供することで、肥大化コードを削減します。
panache は、データベース操作をエンティティ クラスに直接埋め込む Active レコード パターンと、データアクセスロジックを専用のリポジトリ クラスに分離するリポジトリ パターンの両方をサポートしています。Graphus と統合すると、高速なスタートアップ時間と低メモリフットプリントを提供します。panache は、コードをクリーンに維持しつつデータアクセスを簡素化するために、 Hibernetes Object-Relational Maping(ORM) およびJava Persistance API (Java 永続化 API)と連携します。
このチュートリアルでは、Panache を使用して MongoDB データベースで CRUD 操作と集計を実行するための Quarkus アプリケーションをビルドします。アプリケーションでは、書籍を追加、更新、検索、削除する、ジャンルごとに書籍をカウントしたりすることができます。
Tutorial
このチュートリアルでは、次のアクションを実行します。
前提条件を確認します
プロジェクトを設定する
データモデルを作成する
REST APIエンドポイントとなる接続されたデバイスの作成
APIをテストする
前提条件を確認します
開始する前に、次のものをお持ちであることを確認してください。
構成されたクラスターを持つMongoDB Atlasアカウント。Atlas クラスターを設定する方法については、MongoDB の利用を開始するためのガイドを参照してください。
Javaバージョン 21 以降。Javaのインストールの詳細については、Oracleのウェブサイトを参照してください。
ご希望の IDE。
プロジェクトの依存関係を管理するための Maven。
プロジェクトを設定する
Flexibleプロジェクト を保持するためのフォルダーを作成します。このディレクトリに移動し、次のコマンドを実行中て Maven で Queryusプロジェクトを作成します。
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}次のセクションでは、CRUD操作と集計用のさまざまなエンドポイントとなる接続されたデバイスを実装する方法を示します。前の例の強調表示された行の下に、各エンドポイントとなる接続されたデバイスのコードを追加できます。
1 冊の書籍を挿入
次のコードをリソースクラスに追加することで、1 冊の書籍を挿入できます。
@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 で書籍を1件を特定
次のコードをリソースクラスに追加すると、_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 コマンドを実行して、エンドポイントとなる接続されたデバイスをテストできます。
1 冊の書籍を挿入
次の curl コマンドは、1 つの書籍を挿入する方法を示しています。
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" | jq1 冊の書籍を検索
次の 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" | jqTip
jq を使用して JSON 出力を形式化する
前述の例に示すように、jq ツールを使用して、APIからのJSON出力を形式して読みやすくします。jq は、jq ウェブサイトの手順に従ってインストールできます。
追加リソース
このチュートリアルの例の完全なバージョンを表示するには、 MongoDB Githubリポジトリ を参照してください。