我的数据模型看起来像这样:
public class Item {
private List<ItemAttribute> attributes;
// other stuff
}
public class ItemAttribute {
private String name;
private String value;
}
(这显然简化了很多无关的东西)
我想要做的是创建一个查询,要求所有具有一个或多个特定属性的项目,最好与任意AND和OR连接。现在我保持简单,只是试图实现AND案例。在伪SQL(或伪HQL中,如果愿意),它将类似于:
select all items
where attributes contains(ItemAttribute(name="foo1", value="bar1"))
AND attributes contains(ItemAttribute(name="foo2", value="bar2"))
Hibernate文档中的示例似乎没有解决这个特定的用例,但它似乎是一个相当普遍的用例。分离案例也很有用,特别是我可以指定一个可能的值列表,即
where attributes contains(ItemAttribute(name="foo", value="bar1"))
OR attributes contains(ItemAttribute(name="foo", value="bar2"))
-- etc.
这是一个适用于单个属性的示例:
return getSession().createCriteria(Item.class)
.createAlias("itemAttributes", "ia")
.add(Restrictions.conjunction()
.add(Restrictions.eq("ia.name", "foo"))
.add(Restrictions.eq("ia.attributeValue", "bar")))
.list();
学习如何做到这一点将大大有助于扩展我对Hibernate潜力的理解。 :)
答案 0 :(得分:1)
答案 1 :(得分:0)
SELECT item FROM Item item JOIN item.attributes attr
WHERE attr IN (:attrList) GROUP BY item
然后在Java代码中:
List<ItemAttribute> attrList = new ArrayList<ItemAttribute>();
attrList.add(..); // add as many attributes as needed
...// create a Query with the above string
query.setParameter("attrList", attrList);
答案 2 :(得分:0)
为什么以下不起作用?
return getSession().createCriteria(Item.class)
.createAlias("itemAttributes", "ia")
.add(Restrictions.or()
.add(Restrictions.conjunction()
.add(Restrictions.eq("ia.name", "foo1"))
.add(Restrictions.eq("ia.attributeValue", "bar1")))
.add(Restrictions.conjunction()
.add(Restrictions.eq("ia.name", "foo2"))
.add(Restrictions.eq("ia.attributeValue", "bar2"))))
.list();
那将是(name=foo1 && attributeValue=bar1) OR (name=foo2 && attributeValue=bar2)
答案 3 :(得分:0)
我没有测试它,但如果我不得不这样做,我应该尝试解决你的问题:
Map<String,String> map1 = new TreeMap<String,String>();
map1.put("ia.name","foo1");
map1.put("ia.value","bar1");
Map<String,String> map2 = new TreeMap<String,String>();
map2.put("ia.name","foo2");
map2.put("ia.value","bar2");
return getSession().createCriteria(Item.class)
.createAlias("itemAttributes", "ia")
.add(Restrictions.and()
.add(Restrictions.allEq(map1))
.add(Restrictions.allEq(map2))
)
.list();
请告诉我它是否有效。我认为同样适用于或()......
答案 4 :(得分:0)
使用LEFT_OUTER_JOIN来防止“WHERE x = 1 AND x = 2”类型的问题
CreateAlias(“itemAttributes”,“ia”,JoinType.LEFT_OUTER_JOIN)