我有一个使用JOIN和ORDER BY的查询,并想使用Criteria Api在我的存储库中使用它。
在这里,我发现了如何将这样的查询包装到CriteriaQuery(Link)中。
CriteriaQuery<Pet> cq = cb.createQuery(Pet.class); Root<Pet> pet = cq.from(Pet.class); Join<Pet, Owner> owner = cq.join(Pet_.owners); cq.select(pet); cq.orderBy(cb.asc(owner.get(Owner_.lastName),owner.get(Owner_.firstName)));
另一方面,我发现了一些将Criteria Api与JpaRepository结合使用的示例(example)。
问题在于存储库中的所有方法都需要规范:
T findOne(Specification<T> spec);
总是这样构建的:
public static Specification<PerfTest> statusSetEqual(final Status... statuses) { return new Specification<PerfTest>() { @Override public Predicate toPredicate(Root<PerfTest> root, CriteriaQuery<?> query, CriteriaBuilder cb) { return cb.not(root.get("status").in((Object[]) statuses)); } }; }
因此,一方面,我知道如何创建CriteriaQuery;另一方面,我需要从谓词构建的规范,而我不知道如何将CriteriaQuery解析为规范/谓词。
尝试这样的事情(我假设宠物有很多主人):
public static Specification<Pet> ownerNameEqual(String ownerName) { return new Specification<Pet>() { @Override public Predicate toPredicate(Root<Pet> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) { Join<Pet, Owner> owners = root.join("owners"); criteriaQuery.orderBy(criteriaBuilder.desc(root.get("id"))); return criteriaBuilder.equal(owners.get("name"), ownerName); } }; }
这只是搜索至少一个拥有者名称等于 ownerName的 所有宠物的示例 __
但是您可以List<Pet> findByOwnersNameOrderByIdDesc(String ownerName);改为在存储库中添加一个方法(等同于Specification)。
List<Pet> findByOwnersNameOrderByIdDesc(String ownerName);