问题描述
类似的东西:
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));
}