我试图通过JPA选择一些计算数据。查询看起来像这样(示例非常简化):
@Query(value = """
SELECT
a.field1 as f1,
SUM(some clause using joined table) as f2,
SUM(some other clause using joined table) as f3
FROM EntityA a
LEFT JOIN EntityB b ON a.field1 = b.field1
WHERE a.field2 = :field2
""")
Page<ProjectionEntity> getSomeCalculatedData(String field2, Pageable pageable);
如果没有Pageable参数,查询工作正常。当我添加分页时,结果查询包含order by a.f2
,它不存在,因为EntityA
不包含f2
字段。
是否有一种方法如何建立实体结构&从某种程度上说,这个查询是有效的?
火焰持久实体视图就是你要找的。
我创建的库允许JPA模型和自定义接口或抽象类定义模型之间的轻松映射,类似于类固醇上的Spring Data projection。其思想是,您以您喜欢的方式定义您的目标结构(域模型),并通过JPQL表达式将属性(getter)映射到实体模型。
您的用例的DTO模型可以像下面这样使用Blaze-Persistence Entity-Views:
@EntityView(EntityA.class)
public interface ProjectionEntity {
String getField1();
@Mapping("SUM(EntityB[field1 = VIEW(field1)].amount)")
BigDecimal getF2();
@Mapping("SUM(EntityB[field1 = VIEW(field1)].tax)")
BigDecimal getF3();
}
查询是将实体视图应用于查询的问题,最简单的就是通过id进行查询。
ProjectionEntity a = entityViewManager.find(entityManager, ProjectionEntity.class, id);
Spring Data集成允许您几乎像Spring Data projection一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
Page<ProjectionEntity> findAll(Pageable pageable);
最好的部分是,它只会获取实际需要的状态!