Panache とは
Panache は Quarkus に含まれており、簡易的な ORM を提供します。
背後で Hibernate などの ORM を利用しますが、使用者からは ActiveRecord として使用することができます。
Hibernate などの ORM は高度な機能を提供しますが、単純な利用用途であっても定義が複雑になることがあるが、Panache では、Entity の作成をより簡単にすることを目的としています。
Panache Repository を使用
Panache Repository パターンは、データベースとのアクセスする層である repository 層の実装を行います。つまり、使用者はそのクラスに対するテストを作成しなければならない。
本来、 Panache はエンティティクラスで PanacheEntity (PanacheEntityBase) を継承することで、そのクラスが用意している find, create, update, delete メソッドをしようすることで、repository クラスを実装する必要がありません。
Panache Repository を実装しない方法は、また次の機会に説明していこうと思いますが、今回はあえて repository を作成して PanacheRepository を使用する方法を紹介していこうと思います。
Panache Repository を使用した実装
今回は、ビルドツールとして maven を使用します。
以下の依存関係を pom に記載します。こちらの依存ファイルを取得することで PanacheRepository を使用することができます。
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm-panache-common</artifactId>
</dependency>
次に、repository クラスである BookRepositoryImpl クラスを作成します。こちらは、以前に私が作成した図書管理 API を例に使っているのでクラス名に Book とついています。また、こちらのクラスは、interface の実装クラスとなっていますが、こちらも仕様ですので、合わせる必要はありません。
では、以下の PanacheRepository を実装したクラスを作成します。
@ApplicationScoped
public class BookRepositoryImpl implements PanacheRepository<BookEntity>, BookRepository {
}
それでは、ここから CRUD メソッドの紹介をしていきます。
READ
@Override
public Book getById(Integer bookId) {
BookEntity bookEntity = find("id", bookId).firstResult();
return BookEntityMapper.fromEntity(bookEntity);
}
PanacheRepository が用意している find メソッドを使って取得を行います。
第一引数に、取得のキーになるものを指定します。今回は id を指定して取得していますが他のフィールドを指定しても取得できるようです。
また、findById というメソッドも用意されていますが、今回は使用できませんでした。理由は、id が long 型である必要があるからでした。私の実装では、 id が integer だったので使用できませんでしたが、long 型で実装している方は findById を仕様することをおすすめします!
CREATE
@Override
@Transactional
public Book createBook(Book book) {
BookEntity bookEntity = BookEntityMapper.toEntity(book);
persist(bookEntity);
return book;
}
こちらは、Create の処理です。こちらは簡単で、登録したい Entity を作成しておいて、PanacheRepository が用意している persist メソッドを使用することで Create が実装できます。flush もしたいという方は、persistAndFlush というメソッドも用意されています。
UPDATE
@Override
@Transactional
public void updateBook(Book book) {
BookEntity updateBookEntity = BookEntityMapper.toEntity(book);
String query = "title = ?1, " +
"author = ?2, " +
"cost = ?3, " +
"created_at = ?4, " +
"updated_at = ?5" +
"WHERE id = " + updateBookEntity.getId();
update(query, updateBookEntity.getTitle(),
updateBookEntity.getAuthor(),
updateBookEntity.getCost(),
updateBookEntity.getCreatedAt(),
updateBookEntity.getUpdatedAt());
}
こちらは、Update です。Update は少し癖があって、自分で query を作成しなければいけません。PanacheRepository が用意する update メソッドを使って更新処理を行っていくのですが、第一引数に query, 第二引数以降に query のプレースホルダーに入れる値をその数だけ入れていきます。query に埋め込むプレースホルダーは ?1 ?2 のように埋め込んでいきます。1, 2 という数字が引数の順番に対応しています。
DELETE
@Override
public void deleteBook(Integer bookId) {
BookEntity bookEntity = find("id", bookId).firstResult();
delete(bookEntity);
}
こちらは、Delete です。Delete の前に削除対象となるデータのエンティティを先程の find または findById を使って取得します、その後、PanacheRepositoy が用意している delete メソッドを使用して削除することができます。
まとめ
以上で、PanacheRepository を使用した CRUD 処理の説明は終わります。
CRD 処理は比較的直感的に使えて実装が簡単でしたが、Update 処理はこのメソッドをどうやって使うの化を理解するために苦労しました。一度わかってしまえば、公式サイト見ればわかるじゃないかとなるのですが、所見では公式サイトの例もよくわかりませんでした…
コメント