hibernate投影缓存

pvabu6sv  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(336)

我使用jpa进行持久化和缓存(hibernate和redis)。
我有几个表有多列。
在大多数情况下,我只需要检索几个列。但是,业务逻辑查询包含多个连接和复杂的过滤条件。
我正在考虑使用jpql、criteriaapi或本机查询来实现业务逻辑。原生查询最吸引我,因为我可以使用窗口函数和其他特定于db的特性。我只关心缓存效率。对于包含字段子集(投影)的查询,是否休眠已使用的缓存实体?
我相信,不会,唯一的缓存将在查询级别。因此,在这种情况下,使用jpql或criteria api在性能、缓存或其他方面没有任何好处。。。我可以在这里使用直接本机查询,将“cacheable”参数设置为“true”。
你能证实或否定我的理解吗?

7vhp5slm

7vhp5slm1#

你说得对,如果你不是在获取实体而是在获取投影,实体缓存对你没有帮助。您仍然可以使用查询缓存,但是无效是非常粗粒度的,因此您可能看不到很大的好处。我建议你避免缓存,除非你没有其他选择,因为有很多事情可能会出错。当使用适当的索引时,数据库通常足够快,可以处理所有请求,而且通常只扩展数据库比在上面实现复杂的缓存更容易。
话虽如此,我只能建议您看看blaze持久性实体视图,它允许您将投影建模为接口。
blazepersistene是jpa之上的一个查询生成器,它支持jpa模型之上的许多高级dbms特性(以及窗口函数)。我在上面创建了实体视图,以便在jpa模型和自定义接口定义的模型之间进行简单的Map,比如spring数据在steroids上的投影。其思想是以您喜欢的方式定义目标结构,并通过jpql表达式将属性(getter)Map到实体模型。由于属性名被用作默认Map,您基本上不需要显式Map,因为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数据集成允许您像spring数据投影一样使用它:https://persistence.blazebit.com/documentation/entity-view/manual/en_us/index.html#spring-数据特征

相关问题