質問
背景
列のあるテーブルがあります id、imageId、propertyId.
1 つのプロパティに多数のイメージが関連付けられたり、1 つのイメージに多数のプロパティが関連付けられたりする可能性があります。
imageId - many-to-many - propertyId
propertyId のリストがあり、すべての propertyId に関連付けられているすべての画像を調べたいと考えています。 休止状態を使用する.
問題。
ここでは、一度に 1 つのプロパティを選択し、Criteria API を使用して、この propertyId に関連付けられているすべての imageId を検索し、imageId のリストを取得します。次のクエリでこの imageId のリストを使用して、次のように言います。
select imageIds where imageId in (imageIds obtained in previous step) where propertyId = x
したがって、事実上、DB にヒットするクエリの数は propertyId の数と等しくなります。これは良い解決策とは思えません。データベースに n 回アクセスする必要があるため、Detached Query を使用してみましたが、成功しませんでした。もっと良い解決策はありますか?
また、最終的に imageId のリストを取得したとき、それをユーザー セッションに保存してページ付けするのは良い考えですか (結果の数は考慮しないでください) または、プロセス全体を繰り返すのが良いですか、それともすべてページネーションの目的で DB に保存することを検討しますか?
解決
データベース スキーマに問題があるのは次のとおりです。
3 つの個別の関連付け (画像 - コレクション、画像 - プロパティ、コレクション - プロパティ) を 1 つに詰め込もうとしています。 画像コレクション テーブル。これは良いことではありません。おそらくプレーン SQL を使用すればこれを回避できるでしょうが (テーブル内に NULL 列を含む多くの行が必要になります)、Hibernate ではこれを適切にマップすることはできません。ところで、このテーブルには代理主キーは必要ありません。
必要なのは、それを 3 つの別々のテーブルに分割し、モデルを Hibernate で適切な多対多としてマッピングすることです。例えば:
@Entity
public class Image {
@ManyToMany
@JoinTable(
name="IMAGE_PROPERTIES",
joinColumns=@JoinColumn(name="IMAGE_ID"),
inverseJoinColumns=@JoinColumn(name="PROPERTY_ID")
)
private Collection<Property> properties;
...
}
IMAGE_PROPERTIES
テーブルにはのみが含まれます IMAGE_ID
そして PROPERTY_ID
列。あなたは持っています COLLECTION_IMAGES
そして COLLECTION_PROPERTIES
テーブルも同様です。
これにより、次のようなプロパティ名で画像をクエリできるようになります。
from Image img
left join img.properties as prop
with prop.name in ('Tag1', 'Tag2', 'Tag3')
プロパティが実際にタグに似ている場合は、以下を見てください。 この記事 AND / OR / UNION クエリの例については、
プロパティが実際にプロパティである場合 (つまり、所有者エンティティのライフサイクルがあり、同時に複数のエンティティに属することができない)、プロパティを 2 つのテーブル (イメージ用とコレクション用) に分割し、次のテーブルを使用することを検討してください。多くの関連付けに。そうすれば必要なくなります IMAGE_PROPERTIES
そして COLLECTION_PROPERTIES
上から見たテーブル。
他のヒント
あなたが(注:私は、IDEでこれを書いていないので、コードが構文的に正しくないかもしれません):このようなクラスを持っているので、
public class Property {
@ManyToMany
private List<Image> images;
}
public class Image {
@ManyToMany
private List<Property> properties;
}
だから、select property from Property property
のようなクエリを使用すると、通常のJavaプロパティを介して取得することができた、あなたのプロパティのリストを取得する必要があります。
あなたが探しているものということですか、私は質問を誤解したのですか?