taediumの日記

2008-03-12

[] JPQLの集計関数に価値はあるか?

まったく価値がないわけではない。次のようにHAVING句で集計関数を利用してSELECT句でエンティティを返す場合は便利だ。

select d from Department d left outer join d.employees e group by d having count(e) > 5 

Javaのコード上でもエンティティとして受け取ることができる。

String jpql = "select d from Department d left outer join d.employees e group by d having count(e) > 5";
List<Department> list = entityManager.createQuery(jpql).getResultList();

しかし、次のように集計関数をSELECT句に含める場合は便利とはいえない。Javaのコードには結果がObject配列として返されるからだ。

select d.name, count(e), avg(e.salary) from Department d  left outer join d.employees e group by d having count(e) > 5
String jpql = "select d.departmentName, count(e), avg(e.salary) from Department d left outer join d.employees e group by d having count(e) > 5";
List<Object[]> list = entityManager.createQuery(jpql).getResultList();

Object配列ではなく、DTOとして受け取るための仕組みはある。その場合はコンストラクタ式を使う(適切なコンストラクタをもつDTOをあらかじめ作成しておく必要がある)。

String jpql = "select hoge.DepartmentDto(d.departmentName, count(e), avg(e.salary)) from Department d left outer join d.employees e group by d having count(e) > 5";
List<DepartmentDto> list = entityManager.createQuery(jpql).getResultList();

集計結果をどうせDTOにマッピングするならば、JPQLではなくSQLを使いその結果をDTOにマッピングしてもかわらない(Kuina-Daoにはこの機能がある)。エンティティを返さないのならばJPAの特徴である永続コンテキストや遅延ローディングは意味を成さないからだ。

集計のクエリはSQLのツールで試しながらつくりたいだろうからその意味でもSQLで作成が向いているといえる。それに、集計にはRDBMS固有の構文が役立つことが多いためSQLで記述したほうが効率的だ。


JPQLはエンティティを問い合わせる言語であって、集計を扱う言語ではないだろう。

最高なさIKKOさんさ最高なさIKKOさんさ 2008/07/30 17:24 数字みえないわよ。

最高なさIKKOさんさ最高なさIKKOさんさ 2008/07/30 17:25 最高なさIKKOさんさ

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/taedium/20080312/p2
リンク元
Connection: close