私には2つのエンティティ、AblumとImageがあり、これらは多対多の関係にあります。すべてのアルバムとそれらが持っている画像の数を取得するための基準クエリを作成したいと思います。最初にすべてのアルバムを取得してから結果をループしてカウントを取得したくないのは、SQLリクエストが非常に多いためです。私は2泊しましたが、完全に迷子になりました。解決策が見つからない場合は、SQLを使用するためにフォールバックする必要があります。
2 に答える
digitaljoel のインスピレーションのおかげで、CriteriaBuilder にはコレクションに配置できるメソッド呼び出し「size」があることがわかりました。以下はコードです:
CriteriaBuilder cb = getCriteriaBuilder();
CriteriaQuery<Object[]> query = cb.createQuery(Object[].class);
Root<AlbumEntity> albums = query.from(AlbumEntity.class);
query.select(cb.array(albums.get(AlbumEntity_.id), cb.size(albums.get(AlbumEntity_.images))));
query.groupBy(albums.get(AlbumEntity_.id));
ここで groupBy 呼び出しは必須です。そうしないと、エラーが発生します。ただし、このメソッドは、エンティティ自体ではなく、AlbumEntity の ID をロードするためのものです。以下のコードを使用すると、Album エンティティを読み込むことができます。
query.select(cb.array(albums, cb.size(albums.get(AlbumEntity_.images))));
query.groupBy(albums.get(AlbumEntity_.id), ...);
groupBy には、アルバム エンティティのすべてのプロパティを含める必要があります。また、アルバム エンティティに blob 型のプロパティがある場合も機能しません。
JPAマッピングを投稿していないため、いくつかの仮定を行う必要があります。そのため、各アルバムにはList<YourImageClass> images
多対多マッピングがあると想定しています。それで、このようなことがうまくいくでしょう。
select a, size(a.images) from Album a
これは、アルバムがList<Object[]>
どこにあるかを返し、画像コレクションの対応するサイズになります。List.get(i)[0]
List.get(i)[1]
または、単純な Bean を定義して選択することもできます。何かのようなもの
public class AlbumResult {
private Album album;
private Integer imageCount;
public AlbumResult( Album a, Integer size ) {
album = a;
imageCount = size;
}
// getters and setters here
}
それからあなたはすることができます
select new AlbumResult(a, size(a.images)) from Album a;
私はクライテリア クエリを扱ったことはありませんが、JPQL は単純なので、簡単にクライテリア クエリに変換できます。