我有3个问题的表:PrblFldr - > PrblFldrAtrbtVal - > PrblTmpltAtrbt。这些之间的关系是"一对多"和"多对一"分别。
我正在使用CriteriaBuilder
对PrblFldr
个对象进行搜索。我需要搜索与PrblFldrAtrbtVal
相关联的每个PrblFldr
的值。查询参数'密钥是将每个PrblFldrAtrbtVal
与PrblTmpltAtrbt
相关联的唯一PK;参数的值是在PrblFldrAtrbtVal
的值中搜索的内容。
到目前为止我的代码(已编辑):
@GET
@Path("/folders/search")
public Response searchFolders(@Context UriInfo uriInfo) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<PrblFldr> cq = cb.createQuery(PrblFldr.class);
Root<PrblFldr> folder = cq.from(PrblFldr.class);
Join<PrblFldr, PrblFldrAtrbtVal> attributes = folder.join("prblFldrAtrbtVals");
Join<PrblFldrAtrbtVal, PrblTmpltAtrbt> attributeTemplates = attributes.join("prblTmpltAtrbt");
List<Predicate> predicates = new ArrayList<Predicate>();
MultivaluedMap<String, String> queryParams = uriInfo.getQueryParameters();
for (String key: queryParams.keySet()) {
String value = queryParams.getFirst(key).replaceAll("_", "\\\\_");
predicates.add(cb.and(cb.equal(attributeTemplates.<String>get("tmpltAtrbtSeqId"), key),
cb.like(attributes.<String>get("fldrAtrbtVal"), "%" + value + "%", '\\')));
}
cq.distinct(true).select(folder).where(cb.and(predicates.toArray(new Predicate[]{})));
List<PrblFldr> results = em.createQuery(cq).getResultList();
return Response.ok(gson.toJson(results), MediaType.APPLICATION_JSON).build();
}
已编辑:如果我只传入一个键/值对进行搜索,目前正在运行。如果我传入多个PrblFldrAtrbtVal
进行搜索,则返回空白结果集,尽管事实上一个或多个PrblFldr
对象应与指定的PrblFldrAtrbtVal
个对象匹配。 / p>
我认为它与cb.and()
子句中的cq.where()
语句有关。我确实想要&#39; AND&#39;,但为什么回来没有结果呢?
答案 0 :(得分:1)
查询返回一个空列表,因为谓词添加了&#39; AND&#39;。 即,生成的查询类似于;
tmpltAtrbtSeqId = '1' AND fldrAtrbtVal like '%a%'
AND tmpltAtrbtSeqId = '2' AND fldrAtrbtVal like '%b%'
AND tmpltAtrbtSeqId = '3' AND fldrAtrbtVal like '%c%'
传递多个键/值对时。
你需要添加一个&#39; OR&#39; for循环中的子句。