我对通过hibernate缓存教程发现的语句有疑问。
Statement1: - 第一级缓存始终与Session对象关联。 Hibernate默认使用此缓存。
问题1: -
由于此缓存默认保存会话方法的所有结果,例如load,get等。由于将所有对象保留在seeion中,它不会成为主要的内存问题吗?
问题2: -
我们是否需要默认启用此缓存或其缓存?如果需要,我可以禁用一级缓存吗?如果是的话怎么样?
以下问题适用于第一级和第二级缓存
问题3: -
如果我从缓存中获取相同的对象(比如我在同一会话中使用customerid 1加载对象客户两次),则从缓存返回的两个对象将具有与缓存中的对象不同的引用。 对吗?因为如果我更新客户对象中的某个字段,除非调用save / update方法,否则它不应反映在缓存中。
问题4: -
根据我的理解,如果我们尝试从此缓存中第二次从id获取客户对象,它将返回相同的旧对象,即使它们之间已更新。 我们怎样才能确保它是否得到更新它从数据库中读取否则从缓存中读取?我想我们可以使用类似 EHCache
问题5: - 关于查询缓存
我读到了这句话: - 查询中的更新经常发生。因此,对于查询缓存,需要两个缓存区域。
用于存储结果。(缓存标识符值和值类型的结果仅)。 用于存储最新的更新。
我认为“查询中的更新经常发生”意味着我们通常会更改某些参数值,例如select * from customer where custid=?
因此id
将针对不同的客户ID进行更改。因此查询缓存将保留每个查询(以及参数)和每个查询返回的结果。
从右?但不确定为什么我们需要两个缓存区域进行查询缓存?
答案 0 :(得分:4)
AFAIK
答案01:
Hibernate缓存加载的对象,以避免不必要的数据库访问。避免持久性上下文的最简单方法是使用StatelessSession
。无状态Hibernate会话没有脏检查责任,因此可以满足您没有第一级缓存(Persistant Context)的要求。
回答02:
回答03
我很抱歉,但我不理解“更新客户对象并且没有反映在缓存中”背后的概念。我希望该链接澄清您的问题。
回答04
Session.evict()
进行驱逐,但是您可能无法清楚地知道需要驱逐哪些数据。因此,缓存应始终是优化数据库访问的最后一步。
通过重新评估收集关系的关联和获取计划,可以实现良好的优化水平,以避免N + 1选择问题,同时避免。·read-write
缓存策略
符合事务read committed
保护。这是避免dirty reads,但无法帮助repeatable reads。查看EHCache配置here
回答05:查询缓存
查看这些链接,以便更好地理解会话缓存和查询缓存
A. Session Cache
B. Second Level Cache
C. Query Cache
Checkout this link,它简要/简单地解释了查询缓存的结构。
希望这有帮助。