添加一个标准:字符串应该在集合中

我不得不遵循实体对象


@Entity
public class Foobar {
    ...
    private List<String> uuids;
    ...
}

现在我想做一个标准查询来获取所有Foobar pojos的uuids列表包含字符串“abc123”,我只是不确定如何制定适当的标准。


我假设你正在使用实现JPA 2.0的Hibernate版本。 这是一个JPA 2.0解决方案,可以与任何兼容的实现协同工作。

请使用JPA的@ElementCollection注释来注释uuids 。 不要像其他一些答案评论中提到的那样使用Hibernate的@CollectionOfElements 。 后者具有相同的功能,但不推荐使用。

Foobar.java外观大致如下:

@Entity
public class Foobar implements Serializable {

    // You might have some other id
    @Id
    private Long id;

    @ElementCollection
    private List<String> uuids;

    // Getters/Setters, serialVersionUID, ...

}

以下是如何构建CriteriaQuery以选择其uuids包含“abc123”的所有Foobar

public void getFoobars() {
{
    EntityManager em = ... // EM by injection, EntityManagerFactory, whatever

    CriteriaBuilder b = em.getCriteriaBuilder();
    CriteriaQuery<Foobar> cq = b.createQuery(Foobar.class);
    Root<Foobar> foobar = cq.from(Foobar.class);

    TypedQuery<Foobar> q = em.createQuery(
            cq.select(foobar)
              .where(b.isMember("abc123", foobar.<List<String>>get("uuids"))));

    for (Foobar f : q.getResultList()) {
        // Do stuff with f, which will have "abc123" in uuids
    }
}

我在玩这个游戏时做了一个独立的概念验证程序。 我现在无法推出它。 如果你想把POC推到github上,请发表评论。


我知道这是个老问题,但我刚刚遇到了这个问题,并找到了解决办法。

如果你想使用Hibernate Criteria,你可以加入你的uuids集合并使用它的属性elements来匹配元素。 就像那样:

session.createCriteria(Foobar.class)
    .createAlias("uuids", "uuids")
    .add(Restrictions.eq("uuids.elements", "MyUUID"))
    .list() 

我从一年前就发现了这篇文章,如果它可以帮助任何人遇到与我几小时前相同的问题,我已经制定了此方法。

    Public List<EntityObject> getHasString(String string) {
        return getSession().createCriteria(EntityObject.class)
                               .add(Restriction.like("property-name", string, MatchMode.ANYWHERE).ignoreCase();
                           .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                           .list();

对一组字符串也做了同样的处理。

    public List<EntityObject> getByStringList(String[] tab) {
        Criterion c = Restrictions.like("property-name", tab[tab.length-1], MatchMode.ANYWHERE).ignoreCase();
        if(tab.length > 1) {
            for(int i=tab.length-2; i >= 0 ; i--) {
                c = Restrictions.or(Restrictions.like("property-name",tab[i], MatchMode.ANYWHERE).ignoreCase(), c);
            }
        }
        return getSession().createCriteria(EntityObject.class)
                               .add(c)
                           .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
                           .list();
    }

它适用于“或”语句,但可以用“和”语句轻松替换。

链接地址: http://www.djcxy.com/p/37103.html

上一篇: adding a criterion: string should be in collection

下一篇: Hibernate Search: how to search a full name over separate columns