休眠缓存进行投影

时间:2020-05-19 06:38:30

标签: java sql hibernate caching jpql

我使用JPA进行缓存(Hibernate和Redis)的持久性。

我有几个带有多列的表。
在大多数情况下,我只需要检索几列。但是,业务逻辑查询包含多个联接和复杂的过滤条件。

我正在考虑使用JPQL或Criteria API或本机查询来实现业务逻辑。本地查询最吸引我,因为我可以使用窗口函数和其他特定于数据库的功能。 我只关心缓存效率。对于包含字段子集(投影)的查询,Hibernate是否会使用缓存的实体?

我相信,不是唯一的缓存将位于查询级别。 因此,在这种情况下,就性能,缓存或其他方面而言,使用JPQL或标准API没有任何好处。在这里,我可以将“可缓存”参数设置为“ true”使用直接本机查询。

您能确认还是反对我的理解?

1 个答案:

答案 0 :(得分:0)

您是对的,如果您不是在获取实体而是在获取投影,那么实体缓存将无济于事。您仍然可以使用查询缓存,但是失效非常粗糙,因此您可能看不到大的好处。我建议您避免缓存,除非您没有其他选择,否则可能会出错。使用适当的索引时,数据库通常足够快以处理所有请求,并且通常比在顶部实施复杂的缓存更容易扩展数据库。

话虽如此,我只建议您看一下Blaze-Persistence Entity Views,它可以将投影建模为接口。

Blaze-Persitence是JPA之上的查询构建器,它支持JPA模型(还具有窗口功能)之上的许多高级DBMS功能。我在其顶部创建了实体视图,以允许在JPA模型和自定义接口定义的模型之间轻松映射,例如类固醇上的Spring Data Projections。这个想法是您以自己喜欢的方式定义目标结构,并通过JPQL表达式将属性(获取器)映射到实体模型。由于属性名称用作默认映射,因此大多数情况下您不需要显式映射,因为80%的用例都是将DTO作为实体模型的子集。

使用窗口功能的实体视图可能看起来像下面的

@EntityView(Order.class)
public interface OrderTotalPriceDTO {
    Long getId();
    String getCustomer();
    @Mapping("SUM(orderLines.totalPrice)")
    BigDecimal getTotalPrice();
    @Mapping("SUM(SUM(orderLines.totalPrice)) OVER (ORDER BY orderDate)")
    BigDecimal getCummulativeTotalPrice();
}

Spring Data集成使您可以像使用Spring Data Projections一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features