【问题标题】:How to get an interesect query using CritieraQuery?如何使用 Criteria Query 获得相交查询?
【发布时间】:2013-03-19 10:04:02
【问题描述】:

给定

 @Entity
 public class Document {

    @Id
    @Column(name = "DOCUMENT_ID")
    private Long id;

    @ElementCollection
    @CollectionTable(
       name="TAG",
       joinColumns=@JoinColumn(name="DOCUMENT_ID")
    )
    @Column(name="TAG")
    private Set<String> tags;    
 }

查找所有使用特定标签集合标记的文档。本质上,EclipseLink 相当于:

SELECT d FROM Document d WHERE :tag1 MEMBER OF d.tags
INTERSECT
SELECT d FROM Document d WHERE :tag2 MEMBER OF d.tags
...
SELECT d FROM Document d WHERE :tagn MEMBER OF d.tags

但使用 JPA CritieraQuery。

【问题讨论】:

    标签: jpa criteria-api intersect set-intersection criteriaquery


    【解决方案1】:

    使用带有having子句的聚合查询来选择匹配所有必需标签的行:

        CriteriaBuilder cb = entityManager().getCriteriaBuilder();
        CriteriaQuery<Long> q = cb.createQuery(Long.class);
        Root<Document> from = q.from(Document.class);
        List<Predicate> predicates = new ArrayList<Predicate>();
        Expression<Long> id = from.get("id");
    
        Expression<Collection<String>> documentTags = from.get("tags");
        for (String tag : searchedTags) {
            Expression<String> param = cb.literal(tag);
            Predicate predicate = cb.isMember(param, documentTags);
            predicates.add(predicate);
        }
    
        q.multiselect(id).where(
                cb.or(predicates.toArray(new Predicate[0])));
        q.distinct(true);
        q.groupBy(id);
    
        q.having(cb.equal(cb.count(id), searchedTags.size()));
    
        TypedQuery<Long> query = entityManager().createQuery(q);
    

    【讨论】:

      猜你喜欢
      • 2011-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-27
      • 1970-01-01
      • 2018-06-12
      • 2018-01-23
      • 1970-01-01
      相关资源
      最近更新 更多