今のJava EE開発では、JPQLを書く際
- 動的クエリ(Dynamic Query)
- 名前付きクエリ(Named Query)
を使うようにしていて、本来、型のことなど考えるとCriteriaで書くべきだなんだろうな…と思いつつ、可読性や簡易性を優先して上記選択にしています。
ただ、どうしても動的クエリはStringBuilderなどでクエリをダラダラと連結することになって、わりとイケてないらしい…ですね。
ということで、前に@megascusさんがブログで紹介されていたQuerydslを思い出し、これから少し触っていこうかなと。
QuerydslでJPAが思ったよりも捗る
上記ブログ記事の中にあるサンプルコードや、公式サイトのチュートリアルに接頭辞「Q」が付いたEntityクラスみたいなものが出てくるので、なんなんだろあれ?と思ってたのですが、定義したEntityクラスをベースにQuerydslが(というか実際にはapt(Annotation Processing Tool))が自動生成するクラスなんですね。
ってかapt初めて知りました(^^;
ググるとき気を付けないとLinuxのaptが出てきそう…(^^;
……
…
そんなこんな調べつつ、QuerydlsのドキュメントからQuerying JPAのチュートリアルを参考に触ってみました。
Mavenによる依存性定義
pom.xmlは以下としました。
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>3.3.2</version>
</dependency>
公式のみるとslf4jも入れたほうが良いようですね(今回は省略しましたが一応動いてます)。
今日時点で最新の3.3.2は2014年3月24日にリリースされたものなので、わりと最近でもメンテされてるライブラリのようです。
3系の最新定義するなら上記pom.xmlのversionタグを
<version>[3,)</version>
のように指定してもいいかもしれません。
maven-apt-pluginの定義
コード自動生成のためにpom.xmlのbuildタグ内のpluginsで以下定義を追加します。
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>maven-apt-plugin</artifactId>
<version>1.0</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
今回Java EE 7、GlassFish 4.0でサンプルを作りましたが、Entityの生成などはJava EE 6と同様にNetBeans任せで、データベースから自動的に作りました。
そしてビルドすると

EntityのActress.java(NetBeansから自動生成したEntity)に対してQActress.java(Querydls&aptで自動生成)が出来ています。
テーブルサンプル
Actressテーブルは以下定義しました。
ID |
名前 |
年齢 |
1 |
堀北真希 |
25 |
2 |
橋本環奈 |
15 |
3 |
橋本愛 |
18 |
4 |
能年玲奈 |
20 |
5 |
有村架純 |
21 |
サンプルコード
堀北さんをピンポイントで拾ってみます。EJBで
public Actress getHorikita(){
QActress actress = QActress.actress;
JPQLQuery query = new JPAQuery(em, EclipseLinkTemplates.DEFAULT);
return query.
from(actress).
where(actress.name.eq("堀北真希")).
uniqueResult(actress);
}
[ id:1, name:堀北真希, age:25 ]
橋本さんをlike文で検索して、名前でソート昇順に。
public List<Actress> getHashimoto(){
QActress actress = QActress.actress;
JPQLQuery query = new JPAQuery(em, EclipseLinkTemplates.DEFAULT);
return query.
from(actress).
where(actress.name.like("橋本%")).
orderBy(actress.name.asc()).
list(actress);
}
[[ id:3, name:橋本愛, age:18 ], [ id:2, name:橋本環奈, age:15 ]]
成人した女優さん達は
public List<Actress> getAdult(){
QActress actress = QActress.actress;
JPQLQuery query = new JPAQuery(em, EclipseLinkTemplates.DEFAULT);
return query.
from(actress).
where(actress.age.goe(20)).
list(actress);
}
[[ id:1, name:堀北真希, age:25 ], [ id:4, name:能年玲奈, age:20 ], [ id:5, name:有村架純, age:21 ]]
goeは「>=」でgtが「>」。逆はloe、lt。
テーブルが超簡易なのであれですが、良い感じ!
もう少し複雑なクエリ組んでみよう。
これ採用してもいいんじゃないかなー。開発元はmysemaというフィンランドの企業がやっているらしい。
コードはGitHubで管理されてて、わりと活発そうです。
https://github.com/mysema/querydsl
発行されるJPQLをどうやって確認できるのかな?と思ったのですが、普通にNetBeansでも表示されてるっぽい。
