我正在使用Spring 3和Hibernate 3.6开发Web应用程序。目前,我尝试了解Spring和Hibernate的缓存工作原理。我找到了一些有关使用Hibernate进行缓存的资源以及一些有关Spring的资源,现在我尝试将我的信息汇总在一起。我仍然对这两个框架都有一些疑问,如果有人可以回答或告诉我这里列出的事实是否正确,我将很高兴。
在大多数情况下,简短的回答(是/否)就足够了。我认为该列表对于想了解spring和hibernate缓存的工作原理的其他人也很有用。
General
1) Hibernate支持以下缓存:1级缓存,2级缓存,查询缓存
2) Spring本身支持以下缓存可能性:仅方法缓存
1st Level Cache
3) 1级缓存是每个Hibernate应用程序的一部分。
4) 为每个hibernate会话创建1级缓存。
5) 在第一级缓存中保存了什么?对象还是仅仅是它们的属性值?查询及其结果?
2nd Level Cache
6) 我发现:每个应用程序一次使用2级缓存。那不是假的吗?不是每次使用一次SessionFactory吗?和:多个sessionfactorys =可能有多个第二级缓存?
SessionFactory
7) 保存在第二级缓存中的内容:我认为仅属于一个记录的值,而不是对象本身。
8) 当将一个记录中的值存储在2级缓存中时,是否还可以存储相关值(来自通过外键连接的对象)?
9) 当更新二级缓存中一个对象的值时,是否也可以更新与其关联的对象的值?
10) 当对象的值改变时,如何更新二级缓存?冲洗?我可以只更新缓存的一部分,还是必须更新整个缓存?
11) 2级缓存在哪里有意义,在哪里呢?
12) 缓存模式:每个缓存模式是否提供不同的缓存策略?例如,在缓存模式为“只读”的情况下,是否不需要同步数据库和缓存?其他缓存模式是否提供同步?我认为同步必须由开发人员自己完成吗?
Query Cache
13) 查询缓存和二级缓存之间有什么区别?我认为:在查询缓存中保存结果集,但不保存其值,仅保存其ID。当再次使用查询并且结果集仍然“正确”时,从第二级缓存中查询属于这些ID的值
14) 对于查询缓存,必须使用二级缓存吗?
15) 查询缓存在哪里有意义,在哪里呢?
Spring
16) Spring是否提供比方法缓存更多的缓存可能性?
17) 方法缓存未链接到hibernate缓存
18) 但是:对于方法来说,缓存第二级是必要的,例如Ehcache(也可以被hibernate使用)
19) 可以在没有数据库查询的情况下使用方法缓存吗?
Getting mixed up
20) 如果将ehcache用作hibernate二级缓存,将ehcache用作spring用于方法缓存,我可以使用相同的ehcache实例吗?有机会混淆吗?
21) 在使用一级缓存和二级缓存时,它们是否会混淆?查询数据库时,结果是从哪里来的,一级或二级缓存?第一级缓存与第二级缓存一起工作吗?
22) 通过使用我提到的缓存,还有什么可以混淆的吗?:-)
无论有什么问题,谢谢您的回答!:-)
Hibernate支持以下缓存:1级缓存,2级缓存,查询缓存
是。
Spring本身支持以下缓存可能性:仅方法缓存
Spring 3.1引入了基于方法周围注释的新缓存抽象,是的。
1级缓存是每个Hibernate应用程序的一部分。
为每个hibernate会话都创建了一级缓存。
是的,尽管您可以随时手动清除它。
一级缓存中保存了什么?对象还是仅仅是它们的属性值?查询及其结果?
它是会话期间获取的所有对象的映射,如果第二次通过id加载同一对象,则将从L1加载。
我发现:每个应用程序仅使用一次二级缓存。那不是假的吗?是不是每个sessionfactory只使用一次?和:多个sessionfactorys =可能有多个第二级缓存?
没错,通常每个应用程序(数据库)只有一个会话工厂,因此是捷径。
什么存储在第二级缓存中:我认为仅属于一个记录的值,而不是对象本身。
与L1相同,但寿命更长。L2通常由某种工业强度缓存支持,而L1只是一个映射(它甚至不必是线程安全的)。它存储完整的实体,包括延迟加载的关系。
当将一个记录中的值存储到2级缓存中时,是否还可以存储相关值(来自通过外键连接的对象)?
您无需手动管理L2,它会自动发生。
在更新二级缓存中的一个对象的值时,是否也可以更新与其关联的对象在缓存中的值?
往上看。
当对象的值更改时,如何更新二级缓存?冲洗?我可以只更新缓存的一部分,还是必须更新整个缓存?
见上文-Hibernate会为您解决这个问题。您永远不会直接与L2交互。
2级缓存在哪里有意义,在哪里呢?
测量。在通过主键读取大量数据且读写因子很高的应用程序中,L2对您的性能有重大影响。
缓存模式:每个缓存模式是否提供不同的缓存策略?例如,在缓存模式为“只读”的情况下,是否不需要同步数据库和缓存?其他缓存模式是否提供同步?我认为同步必须由开发人员自己完成吗?
缓存模式可帮助Hibernate选择最佳策略进行缓存和无效化。例如,如果缓存是只读的,则Hibernate不会使它失效(或者它不会经常这样做)。但是,只读缓存(只读实体)当然会禁止任何更新。
查询缓存和二级缓存之间有什么区别?我认为:在查询缓存中保存结果集,但不保存其值,仅保存其ID。当再次使用查询并且结果集仍然“正确”时,将从第二级缓存中查询属于这些ID的值。
确实如此,但这是一个非常广泛的话题。特别是 结果集仍然是“正确的” 部分。
对于查询缓存,必须使用二级缓存吗?
是的,没有L2缓存,查询缓存将毫无意义,并且会大大降低应用程序的速度。
查询缓存在哪里有意义,在哪里不有意义?
很难回答的问题,通常是在您多次执行同一查询并且查询参数的范围很低时(对于每组查询参数,都会创建新的查询缓存,并以所有记录ID作为结果)。
与方法缓存相比,Spring是否提供更多的缓存可能性?
不,Spring或多或少只是您自己代码的粘合剂。
方法缓存未链接到hibernate缓存。
Spring没有链接到Hibernate,所以…
但是:对于方法缓存,第二级是必要的,例如ehcache(也可以由hibernate模式使用)
L2是hibernate概念。如果要缓存方法,则需要 一些 基础缓存。随它去吧,是EhCache。当然,它必须是线程安全的。
可以在没有数据库查询的情况下使用方法缓存?
Spring与Hibernate无关。您可能会缓存与数据库无关的计算。
如果将ehcache用于hibernate作为第二级缓存,将ehcache用于spring用于方法缓存,是否可以使用相同的ehcache-instance?有机会混淆吗?
您可以使用与CacheManagerHibernate 相同的缓存配置来简化部署。只要高速缓存名称不重叠,它们就完全独立,甚至可以认为是在同一管理器中工作的。
CacheManager
使用一级缓存和二级缓存时,它们是否会混淆?查询数据库时,结果是从哪里来的,一级或二级缓存?第一级缓存与第二级缓存一起工作吗?
只要某些抽象不会泄漏,它们就可以工作:-)。当您通过主键查询时,首先检查L1(速度更快),然后检查L2。
还有其他什么可以通过使用我提到的缓存混淆的?:-)
参见上文,抽象趋向于泄漏。但是,当您更改数据库时,最严重的问题来了,而Hibernate对此一无所知。同样,没有正确复制的集群也会使您头疼。最大的问题- 错误的缓存通常会减慢应用程序的速度(查询缓存在这里是最危险的)。