Hibernate缓存 vs Spring缓存

5

可以有人解释一下Hibernate二级缓存和Spring缓存之间的区别吗?

在单个应用程序中同时使用它们是否有意义?如果不推荐,请说明何时使用哪个?

如果有人能给出基于真实场景的解释,那将非常有帮助,可以更容易地理解。

3个回答

4
这是两种完全不同的技术。当您使用关系型数据库时,Hibernate和Hibernate Cache通常适用。然后,您可以使用Hibernate ORM生成查询、存储对象等。领域模型是用java编写的(实体)。有时将其中一些实体缓存在内存中以加速查询是有意义的,因此您可以使用Hibernate Cache对它们进行缓存。那里有许多不同类型的缓存,我不会深入细节,因为这是一个普遍性问题,但如果您想了解更多关于Hibernate Caching的信息,请阅读here
现在,Spring缓存是由Spring完成的,总的来说,它与关系型数据库/JDBC世界没有任何关系,换句话说,它在Hibernate的领域之外。您可以将对象缓存起来,以避免例如调用MongoDb或避免重复执行昂贵的计算。您可以将数据缓存在内存中或更先进的分布式技术中,如Hazelcast、Redis或Infinispan(还有其他技术)。

这里你可以找到有关Spring Caching的介绍材料。而这里是更加完整的官方文档。

所以,直接回答你的问题,将两者在一个应用程序中同时使用可能是有意义的 :) 我认为你应该至少了解概念和目标的层面,然后决定在你的情况下适用什么。


1

它们是完全不同的。

  1. hibernate二级缓存

Hibernate二级缓存是在Hibernate上下文中使用的,因此所有会话共享相同的实例。默认情况下它是禁用的,如果要使用它,应该像这样启用:

hibernate.cache.use_second_level_cache=true

为了使一个实体符合二级缓存的要求,我们使用 Hibernate 特有的 @org.hibernate.annotations.Cache 注解来进行注释,并指定缓存并发策略。
一些开发者认为添加标准的 @javax.persistence.Cacheable 注解是一个好习惯(尽管不是 Hibernate 必需的),因此一个实体类的实现可能如下所示: 示例
@Entity
@Cacheable
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Foo {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private long id;

    @Column(name = "NAME")
    private String name;
    
    // getters and setters
}
  1. Spring缓存

如果使用Hibernate二级缓存来缓存JPA实体的实例和查询结果,那么Spring缓存旨在缓存Spring bean。

示例

@Cacheable("addresses")
public String getAddress(Customer customer) {...}

在调用getAddress()方法之前,会首先检查缓存地址,然后再实际调用该方法并缓存结果。

希望我的解释清晰明了。


1
他们之间的主要区别之一是,Hibernate二级缓存会自动帮助维护缓存实体,每当缓存实体有任何更新或删除时,而Spring缓存则是一种更通用的缓存,不知道Hibernate的情况,因此您必须手动使过期的缓存实体无效。
此外,Hibernate二级缓存缓存的实体将由它来管理,而在spring-cache中,它将变为分离状态。如果您不熟悉处理分离实体,则难以处理 它总是取决于上下文是否有意义使用两个缓存。对我来说,使用Hibernate二级缓存需要一些学习曲线才能正确使用。Spring缓存由于其通用性更灵活,但需要自己做更多的工作。
我会首先使用Hibernate二级缓存,因为一旦掌握它,需要做的事情就比较少。如果遇到Hibernate不支持配置我想要的缓存行为的情况,请考虑使用Spring缓存。
我的真实例子是,我有一些后台数据清理任务,需要执行一些本地查询,这导致从二级缓存中删除所有实体,进而影响我的Hibernate查询缓存之一。由于本地查询非常复杂,即使使用此处提到的技巧也无法控制不使缓存失效。因此,我改用Spring缓存来缓存该查询结果。

谢谢@kenchan,这个回答非常有帮助。 - Sachin Dave
很高兴听到这个消息。如果您发现我的答案对您最有帮助,请考虑接受它,以便给我一些支持。谢谢。 - Ken Chan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接