簡體   English   中英

如何從具有多個計數和 Group by 查詢的 Spring Data JPA 返回可分頁的自定義對象?

[英]How to return a pageable custom object from a Spring Data JPA with multiple counts and Group by query?

我已經使用 GROUP BY 查詢從 JPA完成了這個自定義對象,使用一個 SQL 查詢進行了多次計數

以下兩個方法findLaptopTotalQtyfindLaptopQtySummary完美運行

@Query("SELECT "
        + "new com.path.to.LaptopModelCount"
        + "(l.laptopModel AS laptopModel, COUNT(l.laptopModel) AS qty) "
        + "FROM Laptop l "
        + "GROUP by l.laptopModel")
Page<LaptopModelCount> findLaptopTotalQty(Pageable pageable);


@Query("SELECT "
            + "new com.path.to.LaptopModelCount"
            + "(l.laptopModel AS laptopModel, COUNT(l.laptopModel) AS qty,"
            + "sum(case when l.status = 'ready' then 1 else 0 end) AS ready," 
            + "sum(case when l.status = 'partsOnly' then 1 else 0 end) AS partsOnly)"
            + "FROM Laptop l "
            + "GROUP by l.laptopModel")
List<LaptopModelCount> findLaptopQtySummary();

但是,當我更改List<LaptopModelCount> findLaptopQtySummary(); Page<LaptopModelCount> findLaptopQtySummary(Pageable pageable); ,我得到了org.hibernate.hql.internal.ast.QuerySyntaxException: unexpected token: select near...

 LaptopModelCount.Class
package com.path.to;

public class LaptopModelCount {
    long laptopModel;
    long qty;
    long ready;
    long partsOnly;
    public LaptopModelCount(long laptopModel, long qty) {...}
    public LaptopModelCount(long laptopModel, long qty, long ready,long partsOnly) {...}
}

我想 Spring Data 只是不支持,但我不確定。

但是,這是Blaze-Persistence Entity Views的完美用例。

Blaze-Persistence 是一個基於 JPA 的查詢構建器,它支持基於 JPA 模型的許多高級 DBMS 功能。 我在它之上創建了實體視圖,以允許在 JPA 模型和自定義接口定義模型之間輕松映射,例如類固醇上的 Spring Data Projections。 這個想法是您按照自己喜歡的方式定義目標結構,並通過 JPQL 表達式將屬性(getter)映射到實體模型。 由於屬性名稱用作默認映射,因此您通常不需要顯式映射,因為 80% 的用例是具有作為實體模型子集的 DTO。

帶有實體視圖的投影看起來很簡單,如下所示

@EntityView(Laptop.class)
interface LaptopModelCount {
    @IdMapping
    long getLaptopModel();
    @Mapping("COUNT(*)")
    long getQty();
    @Mapping("COUNT(*) FILTER (WHERE status = 'ready')")
    long getReady();
    @Mapping("COUNT(*) FILTER (WHERE status = 'partsOnly')")
    long getPartsOnly();
}

查詢是將實體視圖應用於查詢的問題,最簡單的只是按 id 查詢。

LaptopModelCount dto = entityViewManager.find(entityManager, LaptopModelCount.class, id);

但是 Spring Data 集成允許您幾乎像 Spring Data Projections 一樣使用它: https : //persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features

這將准確創建您期望的查詢,並且還適用於分頁。

Page<LaptopModelCount> findAll(Pageable pageable);

您還可以通過自定義EntityViewSettingProcessor控制要獲取的屬性:

List<LaptopModelCount> findAll(EntityViewSettingProcessor<LaptopModelCount> processor);

因為您可以調用EntityViewSetting.fetch("qty")來覆蓋實際應該獲取的內容,因為您使用具有不同要求的相同模型似乎需EntityViewSetting.fetch("qty")

暫無
暫無

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

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