背景的
我有一个包含列 id,imageId,propertyId 的表。
可能有许多图像与单个属性相关联,并且可能有许多属性与单个图像相关联。
imageId - many-to-many - propertyId
我有一个propertyIds列表,我想找出所有与使用Hibernate 的所有propertyIds 相关联的图像。
问题。的
刚才我一次选择一个属性并使用Criteria API查找与此propertyId关联的所有imageId,我获取了一个imageIds列表。我在下一个查询中使用此imageIds列表并说出
select imageIds where imageId in (imageIds obtained in previous step) where propertyId = x
如此有效,击中数据库的查询数量将等于propertyIds的数量。我不认为这是一个很好的解决方案,不得不点击数据库n次,我尝试使用Detached Query但没有成功。有更好的解决方案吗?
另外,当我最终获得imageIds列表时,将它存储在用户会话和分页中是不是一个好主意(让我们不考虑结果的数量)或重写整个它是一个好主意过程或我是否应考虑将其存储在DB中以用于分页?
答案 0 :(得分:2)
这是您的数据库架构的问题:
您正尝试将3个单独的关联(图像集合,图像 - 属性,集合 - 属性)填充到单个 ImageCollection 表中。这不是一件好事。虽然你可以使用普通的SQL(以该表中包含空列的大量行为代价)来避免这种情况,但是你将无法在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')
如果您的属性非常像标记,请查看this article以获取AND / OR / UNION查询示例。
如果属性确实是属性(即,它们具有所有者实体的生命周期并且不能同时属于多个实体),请考虑将它们分成两个表(一个用于Images,一个用于集合)和使用一对多关联。这样您就不需要上面的IMAGE_PROPERTIES
和COLLECTION_PROPERTIES
表了。
答案 1 :(得分:0)
所以你有一个这样的类(注意:我没有用ide写这个,所以代码可能在语法上不正确):
public class Property {
@ManyToMany
private List<Image> images;
}
public class Image {
@ManyToMany
private List<Property> properties;
}
因此像select property from Property property
这样的查询应该会为您提供属性列表,您可以通过普通的Java属性获取这些属性。
这是你在找什么,还是我误解了这个问题?