0

背景

我有一个包含id、imageId、propertyId列的表。

可能有许多图像与单个属性相关联,并且可能有许多属性与单个图像相关联。

imageId - many-to-many - propertyId

我有一个 propertyIds 列表,我想使用 Hibernate找出与所有 propertyIds 关联的所有图像。

问题。

刚才我一次选择一个属性,并使用 Criteria API 查找与此 propertyId 关联的所有 imageIds,我获得了一个 imageIds 列表。我在下一个查询中使用这个 imageIds 列表并说

select imageIds where imageId in (imageIds obtained in previous step) where propertyId = x

如此有效地,命中数据库的查询数量将等于 propertyId 的数量。我认为这不是一个好的解决方案,不得不访问数据库 n 次,我尝试使用 Detached Query 但没有成功。有更好的解决方案吗?

另外,当我最终获得 imageIds 列表时,将其存储在用户会话中并分页是一个好主意(让我们不考虑结果的数量)还是重复整个过程是个好主意还是应该我考虑将它存储在数据库中是为了分页吗?

4

2 回答 2

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_IDPROPERTY_ID列;你也会有COLLECTION_IMAGESCOLLECTION_PROPERTIES桌子一样的。

然后,您将能够按属性名称查询图像,例如:

from Image img
  left join img.properties as prop
  with prop.name in ('Tag1', 'Tag2', 'Tag3')

如果您的属性真的很像标签,请查看这篇文章以获取 AND / OR / UNION 查询示例。

如果您的属性是真正的属性(也就是说,它们具有所有者实体的生命周期并且一次不能属于多个实体),请考虑将它们分成两个表(一个用于图像,一个用于集合)并使用一个-对许多协会。这样你就不需要上面IMAGE_PROPERTIESCOLLECTION_PROPERTIES表格了。

于 2009-09-22T17:04:28.310 回答
0

所以你有一个这样的类(注意:我没有用 ide 写这个,所以代码可能在语法上不正确):

public class Property {
@ManyToMany
private List<Image> images;
}

public class Image {
@ManyToMany
private List<Property> properties;
}

因此,像这样的查询select property from Property property应该会为您提供属性列表,您可以通过普通的 Java 属性获得这些属性。

那是你要找的,还是我误解了这个问题?

于 2009-09-21T18:05:21.737 回答