我有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
对象匹配,但仍返回空白结果集。我认为这与
cb.and()
子句中的cq.where()
语句有关。我确实想要一个“与”,但是为什么不返回任何结果呢? 最佳答案
查询返回一个空列表,因为谓词添加了“ AND”。
即,正在生成的查询类似于
tmpltAtrbtSeqId = '1' AND fldrAtrbtVal like '%a%'
AND tmpltAtrbtSeqId = '2' AND fldrAtrbtVal like '%b%'
AND tmpltAtrbtSeqId = '3' AND fldrAtrbtVal like '%c%'
当您传递多个键/值对时。
您需要在for循环中添加“ OR”子句。
关于java - 具有一对多和多对一关系的CriteriaQuery,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22637643/