hibernateGrails应用程序中的第二级caching

第一部分

在Grails应用程序中,我知道您可以通过添加为每个域类启用第二级caching

static mapping { cache true } 

默认情况下,二级caching仅在调用get()时使用,但也可以通过将cache true添加到查询来用于条件查询和dynamic查找器。

但是,我仍然不确定我了解查询caching的工作方式。 我最好的猜测是:

  • 每个域类都有单独的查询caching,例如一个用于Book,另一个用于Author
  • 在执行诸如Author.findByName('bob', [cache: true])类的查询之前,计算基于域类(Author),查询(findByName)和查询参数('bob “)。 如果在作者查询caching中find该键,则返回caching的结果而不是执行查询
  • 任何时候作者被保存,删除或更新,作者查询caching刷新

这似乎是合理的,直到我们认为返回Book实例的查询可能会join到Author表中。 在这种情况下,当“作者”被保存,删除或更新时,需要刷新“书本”和“作者”查询caching。 这使我怀疑,也许只有一个单一的查询caching,并且只要保存了任何caching的域类,它就会被清除。

第二部分

在Grails文档中提到了这一点

除了可以使用Hibernate的二级caching来caching实例外,还可以caching对象的集合(关联)。

例如:

 class Author { static hasMany = [books: Book] static mapping = { cache true // Author uses the 2nd level cache books cache: true // associated books use the 2nd level cache } } class Book { static belongsTo = [author: Author] static mapping = { cache true // Book uses the 2nd level cache } } 

上面的configuration是否合理,即如果Author和Book本身使用二级caching,那么使Author-book协会也使用二级caching有什么好处吗?

第三部分

最后,我已经阅读了关于使用第二级查询caching的build议,这意味着它只能用于不常更改的域类。 有什么情况下,不应该为get()操作启用二级caching,也就是说,为什么不将以下内容添加到域类

 static mapping = { cache true // Book uses the 2nd level cache } 

第1部分:

hibernate做正确的事情。 查询caching不是每个实体。 有一个查询caching区域,由所有查询共享,除非您为查询设置特定的区域。 每次更新表时,其时间戳高速caching中的时间戳都会更新。 每次执行查询时,将查询search的每个表的时间戳与caching结果的时间戳进行比较。 当然,只有当itstimestamp比所有表格时间戳更新时,才返回caching的结果。

第2部分:

是的,这是有道理的。 作者的caching记得ID为456的作者的名字是“foo”,出生date是1975/07/19。 只有存储在作者表中的数据被记住。 因此,caching关联也是有用的:在调用author.getBooks() ,不再需要额外的查询来获取作者的书籍集合,Hibernate将从其caching中获取作者书籍的ID,然后加载每本书都来自二级caching。 确保caching书籍,但。

第3部分:

我可以想象几个原因:

  • 有这么多的实体,它们如此改变以至于高速caching命中的数量将非常低,而二级高速caching处理实际上比没有高速caching的解决scheme消耗更多的时间和内存
  • 应用程序是集群化的,分布式二级caching的成本和复杂性过高,收益较低
  • 其他的非Hibernate应用程序写入同一个数据库,因此caching返回陈旧数据的风险很大,这是不可接受的
  • 没有二级caching的情况下,一切都很顺利,没有理由使应用程序比现在复杂。