何时以及如何使用hibernate二级caching?

我无法理解何时hibernate命中二级caching,什么时候使caching无效。

这是我目前所了解的:

  • 二级caching在会话之间存储实体,范围是SessionFactory
  • 你必须告诉哪些实体要caching,默认情况下没有实体会被caching
  • 查询caching将查询结果存储在caching中。

我不明白的是

  • 什么时候hibernate打这个caching?
  • 比方说,我已经设置了二级caching,但不是查询caching。 我想caching我的客户,其中有50000个。 用什么方法可以从caching中检索客户?
  • 我假设我可以通过caching中的id来获取它们。 这将是容易的,但也不值得caching。 但是如果我想和我所有的客户做一些计算呢? 比方说,我想显示一个客户名单,那么我将如何访问他们?
  • 如果查询caching被禁用,我将如何获得我所有的客户?
  • 如果有人更新了其中一个客户,会发生什么?
    • 该客户是否会在caching中失效或所有客户都会失效?

或者我认为caching完全错误? 在这种情况下,更适合使用二级caching的是什么? hibernate文档根本不清楚caching是如何工作的。 只有如何build立它的指示。

更新:所以我已经明白,二级caching(没有查询caching)将是好的加载数据的ID。 例如,我有一个用户对象,我想检查Web应用程序中每个请求的权限。 这是通过在二级caching中caching用户来减less数据库访问的好例子吗? 就像我会将用户ID存储在会话或任何地方,当我需要检查权限,我会加载用户的ID和检查权限。

首先,让我们来讨论一下进程级caching(或者是在Hibernate中调用它的二级caching)。 为了使它工作,你应该

  1. configurationcaching提供者
  2. 告诉hibernate什么实体caching(如果你使用这种映射,在hbm.xml文件中)。

您告诉caching提供程序它应该存储多less个对象以及何时/为什么它们应该失效。 假设你有一个Book和一个Author实体,每次你从DB获取它们,只有那些不在caching中的实际DB才会被选中。 这大大提高了性能。 在以下情况下有用:

  • 您只能通过Hibernate写入数据库(因为需要知道何时更改或使caching中的实体无效)
  • 你经常阅读对象
  • 你有一个单一的节点,你没有复制。 否则,你将需要复制caching本身(使用分布式caching,如JGroups),这增加了更多的复杂性,它不像无共享应用那样好。

那么什么时候caching工作?

  • 当你session.get()session.load()以前select并驻留在caching中的对象。 caching是以ID为关键字,属性为值的存储。 所以只有当有可能通过ID进行search时,才能消除数据库。
  • 当你的关联延迟加载(或者用select而不是连接加载)

但在以下情况下不起作用:

  • 如果您没有通过IDselect。 再次 – 二级caching将实体ID的映射存储到其他属性(它实际上不存储对象,但数据本身),所以如果您的查找如下所示: from Authors where name = :name ,吨打caching。
  • 当你使用HQL(即使你使用where id = ? )。
  • 如果在你的映射中你设置了fetch="join" ,这意味着加载关联连接将被使用,而不是单独的select语句。 仅当使用fetch="select"进程级高速caching才能在子对象上工作。
  • 即使你有fetch="select"但是在HQL中你使用连接来select关联 – 那些连接会马上发出,他们会覆盖你在hbm.xml或注释中指定的任何东西。

现在,关于查询caching。 你应该注意到,它不是一个单独的caching,它是对进程级caching的补充。 假设你有一个国家实体。 它是静态的,所以你知道每当你from Countryfrom Country会有相同的结果集。 这是查询caching的完美候选者,它将自己存储一个ID列表,当下一次select所有国家时,它将把这个列表返回到进程级caching,而后者则会返回每个ID的对象因为这些对象已经存储在二级caching中。 每次与实体相关的任何变化时,查询caching都将失效。 假设您将from Authorsconfiguration为放置在查询caching中。 由于作者经常改变,所以不会有效。 所以你应该只使用查询caching来处理更多或更less的静态数据。

  • 二级caching是一个键值存储。 它只适用于你通过id获得你的实体
  • 当通过hibernate来更新/删除实体时,二级caching被无效/更新。 如果以不同的方式更新数据库,则不会失效。
  • 查询(例如客户列表)使用查询caching。

实际上,有一个键值分布式caching是非常有用的 – 这就是memcached的function,它为Facebook,Twitter等等提供支持。 但是,如果你没有通过id查找,那么它不会很有用。

晚了,但想系统地回答这个问题,许多开发商问。

一个接一个的问题就是我的答案。

Q.什么时候hibernate打这个caching?

A. 一级高速caching会话对象相关联。 二级caching会话工厂对象相关联。 如果在第一个中没有find对象,那么检查第二个级别。

问:比方说,我已经设置了二级caching,但没有查询caching。 我想caching我的客户,其中有50000个。 用什么方法可以从caching中检索客户?

答:你有更新的答案。 另外,查询caching仅存储对象的ID列表,而那些对象的ID将存储在相同的二级caching中。 所以如果你启用查询caching,你将使用相同的资源。 整洁的权利?

问:我假设我可以通过caching中的id来获取它们。 这将是容易的,但也不值得caching。 但是如果我想和我所有的客户做一些计算呢? 比方说,我想显示一个客户名单,那么我将如何访问他们?

A.回答上面。

问:如果查询caching被禁用,我将如何获得我的所有客户?

A.回答上面。

问:如果有人更新了其中一个客户会发生什么情况? 该客户是否会在caching中失效或所有客户都会失效?

答:Hibernate不知道,但你可以使用其他第三方IMDG /分布式caching实现为hibernate二级caching,并使其失效。 例如TayzGrid就是这样的一个产品,我猜测的更多。