簡體   English   中英

如何在Spring Data中進行“按聚合函數排序”?

[英]How to make “order by aggregate function” in Spring Data?

我有兩個實體:

的resourcefile:

@Entity
@Table(name = "resource_file")
public class ResourceFile extends IdEntity<Integer> {

    @Id
    @SequenceGenerator(name = "resource_file_id_generator", sequenceName = "resource_file_id", allocationSize = 1)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "resource_file_id_generator")
    @Column(name = "id", unique = true, nullable = false)
    @Nonnegative
    private Integer id;

    ...
}

FavoriteResourceFile:

@Entity
@Table(name = "favorite_resource_file")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class FavoriteResourceFile extends IdEntity<FavoriteResourceFileId> {

    @EmbeddedId
    private FavoriteResourceFileId id;

    @MapsId("resourceFileId")
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "resource_file_id", nullable = false)
    private ResourceFile resourceFile;

    ...

}

我想進行以下查詢“選擇所有資源文件並按喜歡的資源文件的計數對它們進行排序”。

在SQL中它看起來像:

select rf.id, count(frf.resource_file_id) from resource_file rf
left join favorite_resource_file frf on frf.resource_file_id = rf.id
group by rf.id
order by count(rf.id) desc;

但我無法理解如何使用Spring Data以及如何在最后映射到ResourceFile實體。

一些限制:

  • 我無法在ResourceFile中與FavoriteResourceFile建立關系,因為它們位於不同的模塊中
  • 我不想使用本機SQL或JPA查詢(作為字符串)。
  • 最好使用元模型,規范或QueryDSL,因為它們已經在項目中使用。

有人能幫我嗎?

您可以使用自定義存儲庫實現以及Crud / PagingAndSorting存儲庫實現,如下所示:

終點回購:

public interface ResourceFileRepository extends
    PagingAndSortingRepository<ResourceFile, Integer>,
    ResourceFileRepositoryCustom {
}

定制回購:

public interface ResourceFileRepositoryCustom {
    List<ResourceFile> getResourceFilesOrderByFavourites();
}

使用實際代碼自定義repo實現以按最喜歡的計數順序檢索ResourceFile(注意它是ResourceFileRepositoryImpl而不是ResourceFileRepositoryCustomImpl)。

我沒有那些嵌入式鍵,所以我不得不簡化一下。 查詢來自FavoriteResourceFile,因為ResourceFile與FavoriteResourceFile沒有自己的關系。

public class ResourceFileRepositoryImpl implements ResourceFileRepositoryCustom {
    @PersistenceContext
    private EntityManager em;

    public void setEntityManager(EntityManager em) {
        this.em = em;
    }

    @Override
    public List<ResourceFile> getResourceFilesOrderByFavourites() {
        CriteriaBuilder criteriaBuilder = this.em.getCriteriaBuilder();
        CriteriaQuery<ResourceFile> q = criteriaBuilder
                .createQuery(ResourceFile.class);
        Root<FavoriteResourceFile> root = q.from(FavoriteResourceFile.class);
        Join<FavoriteResourceFile, ResourceFile> join = root.join(
                 FavoriteResourceFile_.resourceFile, JoinType.LEFT);
        q.select(join);
        q.groupBy(join.get(ResourceFile_.id));
        q.orderBy(criteriaBuilder.desc(
                      criteriaBuilder.count(
                          join.get(ResourceFile_.id))));

        TypedQuery<ResourceFile> query = this.em.createQuery(q);
        return query.getResultList();
    }
}

要查看完整的示例項目(使用一些非常基本的SQL和測試) - checkout / fork / etc: https//github.com/rchukh/StackOverflowTests/tree/master/13669324

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM