投影的休眠缓存

问题描述 投票:0回答:1

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

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

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

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

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

java sql hibernate caching jpql
1个回答
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

© www.soinside.com 2019 - 2024. All rights reserved.