Hibernate查询集合中的多个项目

时间:2010-06-08 20:42:25

标签: java hibernate

我的数据模型看起来像这样:

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潜力的理解。 :)

5 个答案:

答案 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)