DeltaSpike Dataの紹介
2015/12/10 コメントを残す
DeltaSpike Dataモジュールは、Repositoryパターンを実現したモジュールです。JPAを使ったプログラミングでは同様なコードを何度も書く必要があります。Dataモジュールを使うとデータベースへのCRUD関連の機能やクエリ定義をリポジトリインタフェースに集約することができます。さらに、DTO (Data Transfer Object)とエンティティの間のマッピングを提供するなど、なかなか面白い機能も提供しています。
Dataモジュールを使ってリポジトリを作るには次のようなインタフェースを用意します。
- @Repositoryアノテーションをつける
- org.apache.deltaspike.data.api.EntityRepositoryを拡張する
例えば、Memberというエンティティクラスがあって、主キーの型がLongの場合、次のようにしてリポジトリを定義します。
@Repository public interface MemberRepository extends EntityRepository<Member, Long> {}
たったこれだけで、JPAのAPIを使うことなく、Entityに簡単にアクセスできるようになります。EntityRepositoryインタフェースは、以下のようなメソッドを提供しています(雰囲気を伝えるため代表的なものをピックアップしています)。
- E save(E entity)
- void remove(E entity)
- void refresh(E entity)
- void flush()
- E findBy(PK pk)
- List<E> findAll()
- Long count();
DeltaSpike Dataの簡単な使い方
リポジトリは@Injectで変数にインジェクトして使います。インジェクトのときに指定する型は@Repositoryをつけたインタフェースです。例えば、エンティティを保存するには次のようにします。
@Inject private MemberRepository repository; Member member = new Member(); member.setName("Neverbird"); member.setEmail("neverbird@mail.com"); member.setPhoneNumber("1234567890"); repository.save(member);
実装クラスがなくともリポジトリを利用できる理由
さて、ここまででリポジトリの実装クラスが登場していないのに気付きましたか? DeltaSpikeを使うと、インタフェースを宣言するだけでリポジトリを利用できるのです。実は、これは前回のブログ記事で紹介したPartialBeanモジュールを使っています。@Repositoryアノテーションのソースを確認すると、確かに@PartialBeanBindingを使って定義されています。
@Stereotype @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @Inherited @PartialBeanBinding public @interface Repository { Class forEntity() default Object.class; String methodPrefix() default ""; }
PartialBeanは、インタフェースへのアクセスからInvocationHandlerへの呼び出しを行う仕組みを提供します。DeltaSpike DataモジュールはEntityRepositoryインタフェースのJPAによる実装をInvocationHandlerとして提供しています。@Repositoryを使ってリポジトリのインタフェースを宣言することで、リポジトリインタフェースへの呼び出しが内部でInvocationHandlerの呼び出しに変換されているのです。
セットアップ
DeltaSpike Dataモジュールを使うためにはpom.xmlに以下の依存ライブラリを追加します。
<dependency> <groupId>org.apache.deltaspike.modules</groupId> <artifactId>deltaspike-data-module-api</artifactId> <version>${version.deltaspike}</version> </dependency> <dependency> <groupId>org.apache.deltaspike.modules</groupId> <artifactId>deltaspike-data-module-impl</artifactId> <version>${version.deltaspike}</version> </dependency>
クエリの定義
EntityRepositoryインタフェースにはfindByとfindAllしか検索方法が提供されていません。これでは実際のアプリケーションでは使い物にならないのでEntity定義に合わせて必要な検索のためのメソッドをリポジトリに追加します。
@Repository public interface MemberRepository extends EntityRepository { @Query("select m from Member m where m.email = ?1") public Member findByEmail(String email); }
DeltaSpike Dataモジュールの最大の特徴はクエリの定義方法です。上の例は検索メソッドに@Queryというアノテーションを付加することでクエリを定義しています。@Queryで指定しているのはJPAでサポートしているJPQLの文字列です。findByEmailメソッドの例のように検索メソッドに引数を指定することもできます。一見してわかるように、この書き方を使うとJPQLの式と検索メソッドの結びつきを直感的に理解することができます。
リポジトリのユーザーは以下のようにリポジトリに定義されたクエリのメソッドを呼び出します。
@Inject private MemberRepository repository; Member member = repository.findByEmail("neverbird@email.com")
DeltaSpike Dataの最大の特徴はクエリ定義だと思います。Dataモジュールでは@Query以外にも豊富なクエリの定義方法を提供しています。次回は、WildFly上で実際にDeltaSpike Dataを動かしながら、その機能を確認していきましょう。