spring-data-jpa 在链接多个规格时使用orderBy

9nvpjoqh  于 2022-11-10  发布在  Spring
关注(0)|答案(2)|浏览(171)

existing example不适合我的场景,它检查是否存在要排序的参数。在我的情况下,我只想按DESC顺序的列(created_on)排序。
因此,下面是我最后要调用的规范的定义,在链接了“其他的:

public static Specification<Event> orderByCreationDate() {
        return new Specification<Event>() {
            @Override
            public Predicate toPredicate(Root<Event> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
                query.orderBy(criteriaBuilder.desc(root.get("created_on")));
                return null;
            }
        };
    }

使用lambda的简化版本如下所示:

public static Specification<Event> orderByCreationDate() {
        return (root, query, criteriaBuilder) -> {
            query.orderBy(criteriaBuilder.desc(root.get("created_on")));
            return null;
        };
    }

以下是规范的完整链接调用:

Page<Event> eventsPage = historyLogRepository.findAllPaginated(
                                    allEventsWithEventTypesByVaultId(vaultId)
                                    .and(hasNoEventTypeVisibility()).or(hasEventTypeVisibility(visibilities))
                                    .and(hasNoEventTypes()).or(hasEventTypes(types))
                                    .and(creationDateBefore(before))
                                    .and(creationDateAfter(after))
                                    .and(hasNoDocumentId()).or(hasDocumentId(documentId))
                                    .and(orderByCreationDate()),
                                    pageable);

我们的想法是替换以下本机查询:

@Query(value = "SELECT * FROM event e " +
            "INNER JOIN event_type et ON et.id = e.event_type_id " +
            "WHERE e.vault_id = :vaultId AND " +
            "(COALESCE(:visibilities) IS NULL OR et.visibility IN (:visibilities)) AND " +
            "(COALESCE(:types) IS NULL OR et.name in (:types)) AND " +
            "(:before IS NULL OR e.created_on < :before) AND " +
            "(:after IS NULL OR e.created_on > :after) AND " +
            "(:documentId IS NULL OR e.document_id = :documentId) " +
            "ORDER BY e.created_on DESC LIMIT :limit", nativeQuery = true)
    List<Event> findAll(@Param("vaultId") String vaultId,
                        @Param("before") LocalDateTime before,
                        @Param("after") LocalDateTime after,
                        @Param("limit") Integer maxNumberOfResults,
                        @Param("types") List<String> types,
                        @Param("visibilities") List<String> visibilities,
                        @Param("documentId") String documented);

新的使用规格:

Page<Event> findAllPaginated(Specification<Event> specification, Pageable pageable);
...

有什么想法吗?在这种情况下,我应该从toPredicate方法返回什么?

wfauudbj

wfauudbj1#

null应该是正确的,而且通常是有效的。如果你想明确,return criteriaBuilder.conjunction()表示总是为真的东西--类似地,disjunction()表示总是为假的东西。

Predicate conjunction()

创建一个合取(具有零个合取)。具有零个合取的合取为真。

Predicate disjunction()

创建一个析取项(具有零个析取项)。具有零个析取项的析取项为假。

pcrecxhr

pcrecxhr2#

据我所知,你已经为每个参数做了方法,现在你只需要把它们组合起来,我有一些类似的代码,如下所示
说明:代码检查是否为空,如果为空则返回真,否则返回所需规范。

public static Specification<Post> byAuthorNames(String[] authorNames) {
        return (root, query, criteriaBuilder) -> {
            if (authorNames == null || authorNames.length == 0) {
                return criteriaBuilder.conjunction();
            }
            return root.<String>get("author").in(authorNames);
        };
    }

组合多个规格:

public Specification<Post> findByFilters(String search, String[] authorNames, String[] tagNames) {
        return byPublished()
                .and(bySearch(search))
                .and(byAuthorNames(authorNames))
                .and(byTagNames(tagNames));
    }

相关问题