Java JpaSpecificationExecutor JOIN + ORDER BY in Specification

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37203878/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:06:02  来源:igfitidea点击:

JpaSpecificationExecutor JOIN + ORDER BY in Specification

javamysqljpaspring-data-jpacriteria-api

提问by aschi

I have a query using a JOIN and ORDER BY and want to use it within my repository using the Criteria Api.

我有一个使用 JOIN 和 ORDER BY 的查询,并希望使用 Criteria Api 在我的存储库中使用它。

Here I found, how to wrap such a query into a CriteriaQuery (Link).

在这里我发现,如何将这样的查询包装到 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)));

On the other side, I found some examples to use the Criteria Api in Combination with a JpaRepository (example).

另一方面,我找到了一些将 Criteria Api 与 JpaRepository 结合使用的示例(示例)。

The Problem is that all methods in the repository expect a Specification:

问题是存储库中的所有方法都需要规范:

T findOne(Specification<T> spec);

which is always build like this:

它总是像这样构建:

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));
        }
    };

}

So at one side I know how to create a CriteriaQuery, and on the other side I need a Specification which is build from a Predicate, and I can not figure out how to parse the CriteriaQuery into a Specification/Predicate.

因此,一方面我知道如何创建 CriteriaQuery,另一方面我需要一个从谓词构建的规范,我不知道如何将 CriteriaQuery 解析为规范/谓词。

采纳答案by Jakub Bibro

Try something like this (I assumed pet has many owners):

尝试这样的事情(我假设宠物有很多主人):

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);
            }
        };
    }

This is just an example to search all pets whose at least one owner has name equal to ownerName

这只是一个示例,用于搜索至少一个主人的名字等于ownerName 的所有宠物

But you could add a method List<Pet> findByOwnersNameOrderByIdDesc(String ownerName);in your repository instead (as an equivalent to Specification).

但是您可以List<Pet> findByOwnersNameOrderByIdDesc(String ownerName);改为在您的存储库中添加一个方法(相当于规范)。