【发布时间】:2022-02-04 20:41:43
【问题描述】:
谁能解释一下hibernate二级缓存和spring缓存有什么区别?
在单个应用程序中同时使用两者是否有意义?如果不推荐,那么什么时候使用呢?
如果有人给出基于现实生活场景的解释,它可以帮助您轻松理解。
【问题讨论】:
标签: spring spring-boot hibernate spring-cache hibernate-cache
谁能解释一下hibernate二级缓存和spring缓存有什么区别?
在单个应用程序中同时使用两者是否有意义?如果不推荐,那么什么时候使用呢?
如果有人给出基于现实生活场景的解释,它可以帮助您轻松理解。
【问题讨论】:
标签: spring spring-boot hibernate spring-cache hibernate-cache
这是两种完全不同的技术。当您使用关系数据库时,Hibernate 和 Hibernate Cache 通常适用。然后就可以使用Hibernate ORM来生成查询、存储对象等。领域模型是用java(entities)写的。有时将其中一些实体缓存在内存中以加快查询速度是有意义的,因此您可以使用 Hibernate Cache 缓存它们。那里有很多不同种类的缓存,我不会深入细节,因为这是一个普遍的问题,但如果你想了解更多关于 Hibernate 缓存的信息,请阅读here
现在 Spring 缓存由 Spring 完成,一般来说,它与关系数据库/JDBC 世界无关,换句话说,在 Hibernate 领域之外。您可以缓存一个对象以避免,例如,调用 MongoDb,或者避免进行两次昂贵的计算。您可以将数据缓存在内存中或更高级的分布式技术中,例如 Hazelcast、Redis 或 Infinispan(还有其他)。
Here 你可以找到 Spring Caching 的介绍材料。而this则是官方文档更完整的方式
所以,是的,要直接回答您的问题,在一个应用程序中同时使用两者可能是有意义的 :) 我真的认为您应该熟悉这两者,至少在概念及其目标的层面上,然后决定什么适用于您的情况。
【讨论】:
他们完全不同
Hibernate 二级缓存是在 Hibernate 的上下文中使用的,所以所有的 session 共享同一个实例。默认情况下它是停用的,为了使用它,你应该像这样启用它:
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
}
如果 Hibernate 二级缓存用于缓存 JPA 实体的实例和查询结果,则 Spring 缓存旨在缓存 Spring bean。
示例
@Cacheable("addresses")
public String getAddress(Customer customer) {...}
getAddress() 调用将在实际调用方法之前首先检查缓存地址,然后缓存结果。
我希望我的解释很清楚
【讨论】:
它们的主要区别之一是休眠二级缓存将自动帮助维护缓存的实体,只要缓存实体有任何更新或删除,而 Spring 缓存是一个更通用的缓存,它对 Hibernate 一无所知,所以你有在这种情况下手动使陈旧的缓存实体失效。
Hibernate 二级缓存缓存的实体也将由它管理,而在 spring-cache 中它将被分离。如果您不熟悉,请处理分离的实体is not easy。
使用两个缓存是否有意义总是取决于上下文。对我来说,使用 Hibernate 二级缓存需要一些学习曲线才能正确使用它。 Spring 缓存由于其通用性而更加灵活,但需要您自己完成更多工作。
我会首先使用 Hibernate 二级缓存,因为一旦你掌握了它,它就需要做更少的事情。如果遇到 Hibernate 不支持配置我想要的缓存行为的情况,请考虑使用 Spring 缓存。
我的真实例子是我有一些后台数据清理任务,需要执行一些本机查询,这会导致从二级缓存中删除所有实体,这反过来会影响我的休眠查询缓存之一。由于本机查询非常复杂,即使使用here 中提到的提示,我也无法控制不使缓存无效。所以我改用 Spring 缓存来缓存那个查询结果。
【讨论】: