如何编写用于从列表中全选的条件查询生成器?

问题描述

我需要一个查询,该查询将仅返回具有列表中所有值的结果。

类似的东西:

SELECT * 
FROM ads_tags 
WHERE tag_value("a","b","c");

我知道查询效果不好,但关键是我想过滤广告,但只过滤列表中具有所有标签的广告。

使用我的代码,我从列表中获得了所有带有至少一个标签的广告。那是因为我正在使用IN接口。

@Override
public List<AdsDTO> findAll(AdsSubGroup adssubgroup,Long userId,String status,String adsType,String businessType,Long adsGroupId,String region,Integer fromPrice,Integer toPrice,Boolean fixedPrice,Boolean freeDelivery,Boolean productWarranty,Boolean urgentSales,Boolean hasImage,Integer pageNumber,Integer pageSize,List<String> tags) {

    CriteriaBuilder builder = em.getCriteriaBuilder();
    CriteriaQuery<Ads> query = builder.createquery(Ads.class);
    Root<Ads> ads = query.from(Ads.class);
    // query.orderBy(builder.desc(ads.get("adsDate")));
    List<Predicate> predicates = new ArrayList<>();
    Join<Ads,JwtUser> adsUsersJoin = ads.join("users");
    Join<Ads,AdsSubGroup> adsAdsSubGroupJoin = ads.join("adssubgroup");
    Join<Ads,Tag> tagsJoin = ads.join("adsTags");
    In<List<String>> in = builder.in(tagsJoin.get("name"));


    if (tags != null && tags.size() > 0) {
        // in.value(tags);
        tags.forEach(tag - > in.value(tags));
        /*
         * for (String tag : tags) { in.value(tag);
         *
         * }
         */
        predicates.add(in);
    }

    query.select(ads);
    query.distinct(true);
    query.where(predicates.toArray(new Predicate[0]));
    if (!(pageNumber == null && pageSize == null)) {
        TypedQuery<Ads> typedQuery = em.createquery(query);
        typedQuery.setFirstResult((pageNumber - 1) * pageSize);
        typedQuery.setMaxResults(pageSize);
        List<Ads> adsList = typedQuery.getResultList();
        return AdsConverter.convertToAdsDTO(adsList);
    } else {
        List<Ads> adsList = em.createquery(query).getResultList();
        return AdsConverter.convertToAdsDTO(adsList);
    }
}

要从列表中获取所有带有ALL标签的广告,而不是至少一个,我需要写些什么而不是In接口?

解决方法

列表中每个Tag类型的元素都需要一个联接。 修复代码很困难,因为它不是一个最小的示例,但是以下示例应该有所帮助:

CriteriaQuery<Ads> query = builder.createQuery(Ads.class);
Root<Ads> ads = query.from(Ads.class);
List<Predicate> predicates = new ArrayList<>();
for (String tag : tags) {
    Join<Ads,Tag> tagsJoin = ads.join("adsTags");
    predicates.add(builder.equal(tagsJoin.get("name"),tag));
}