Java 如何从具有多个计数和分组查询的Spring数据JPA返回可分页自定义对象?
我做了这件事 以下两种方法Java 如何从具有多个计数和分组查询的Spring数据JPA返回可分页自定义对象?,java,spring,hibernate,jpa,spring-data-jpa,Java,Spring,Hibernate,Jpa,Spring Data Jpa,我做了这件事 以下两种方法findLaptopTotalQty和findLaptopQtySummary运行良好 @Query("SELECT " + "new com.path.to.LaptopModelCount" + "(l.laptopModel AS laptopModel, COUNT(l.laptopModel) AS qty) " + "FROM Laptop
findLaptopTotalQty
和findLaptopQtySummary
运行良好
@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();
我猜Spring数据并不支持这一点,但我不确定 然而,这是一个完美的用例 Blaze Persistence是JPA之上的查询生成器,它支持JPA模型之上的许多高级DBMS功能。我在它上面创建了实体视图,以便在JPA模型和自定义接口定义的模型之间轻松映射,类似于类固醇上的Spring数据投影。其思想是以您喜欢的方式定义目标结构,并通过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进行查询
laptomodelcount dto=entityViewManager.find(entityManager,laptomodelcount.class,id)代码>
但是Spring数据集成允许您像使用Spring数据投影一样使用它:
这将准确地创建您所期望的查询,并可用于分页
Page<LaptopModelCount> findAll(Pageable pageable);
在这种情况下,您可以调用EntityViewSetting.fetch(“qty”)
来覆盖实际应该获取的内容,这似乎是您在使用具有不同需求的同一模型时所需要的
@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();
}
Page<LaptopModelCount> findAll(Pageable pageable);
List<LaptopModelCount> findAll(EntityViewSettingProcessor<LaptopModelCount> processor);