何时以及如何使用休眠二级缓存? [英] When and how to use hibernate second level cache?

查看:27
本文介绍了何时以及如何使用休眠二级缓存?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我无法理解 hibernate 何时命中二级缓存以及何时使缓存无效.

I have trouble understanding when hibernate hits the second level cache and when does it invalidate the cache.

这是我目前的理解:

  • 二级缓存存储会话之间的实体,作用域是SessionFactory
  • 您必须告诉要缓存哪些实体,默认情况下不会缓存任何实体
  • 查询缓存将查询结果存储在缓存中.

我不明白的是

  • hibernate 什么时候命中这个缓存?
  • 假设我已经设置了二级缓存,但没有设置查询缓存.我想缓存我的客户,他们有 50000 个.我可以通过什么方式从缓存中检索客户?
  • 我假设我可以通过缓存中的 id 获取它们.这很容易,但也不值得缓存.但是,如果我想对所有客户进行一些计算,该怎么办?假设我想显示客户列表,那么我将如何访问他们?
  • 如果禁用查询缓存,我将如何获得所有客户?
  • 如果有人更新了其中一位客户,会发生什么?
    • 该客户会在缓存中失效还是所有客户都会失效?

    或者我认为缓存完全错误?在这种情况下,二级缓存的更合适用途是什么?休眠文档根本不清楚缓存在现实中是如何工作的.只有有关如何设置的说明.

    Or am I thinking caching totally wrong? What would be more appropriate uses of second level cache in that case? The hibernate documentation is not at all clear how the cache works in reality. There are only instructions on how to get it set up.

    更新:所以我开始明白二级缓存(没有查询缓存)对于通过 id 加载数据很有用.例如,我有一个用户对象,我想检查 Web 应用程序中每个请求中的权限.这是通过将用户缓存在二级缓存中来减少数据库访问的好方法吗?就像我将用户 ID 存储在会话中或任何需要检查权限的地方一样,我会通过它的 ID 加载用户并检查权限.

    Update: So I've come to understand that second level cache(without query cache) would be good for loading data by id's. For example I have user object that I want to check for permissions in every request in a web application. Would this be a good case to reduce database access by caching the user in the second level cache? Like I would store the user id in the session or wherever and when I need to check for permissions I would load the user by it's id and check permissions.

    推荐答案

    首先,让我们谈谈进程级缓存(或 Hibernate 中的二级缓存).为了让它发挥作用,你应该

    First of all, let's talk about process level cache (or 2nd level cache as they call it in Hibernate). To make it work, you should

    1. 配置缓存提供程序
    2. 告诉 hibernate 缓存哪些实体(如果使用这种映射,则直接在 hbm.xml 文件中).

    你告诉缓存提供者它应该存储多少个对象,以及它们应该在什么时候/为什么失效.所以假设你有一个 Book 和一个 Author 实体,每次你从数据库中获取它们时,只有那些不在缓存中的才会从实际的数据库中选择.这显着提高了性能.在以下情况下很有用:

    You tell to the cache provider how many objects it should store and when/why they should be invalidated. So let's say you have a Book and an Author entities, each time you're getting them from the DB, only those that are not in cache will be selected from actually DB. This increases performance significantly. It's useful when:

    • 您只能通过 Hibernate 写入数据库(因为它需要一种方法来知道何时更改或使缓存中的实体无效)
    • 您经常阅读对象
    • 您只有一个节点,并且没有复制.否则,您将需要复制缓存本身(使用分布式缓存,如 JGroups),这会增加更多的复杂性,而且它的扩展性不如无共享应用.

    那么缓存什么时候起作用?

    So when does cache work?

    • 当您 session.get()session.load() 之前选择并驻留在缓存中的对象时.缓存是一种存储,其中 ID 是键,属性是值.因此,只有当有可能通过 ID 进行搜索时,您才能避免访问数据库.
    • 当你的关联是延迟加载的(或者用选择而不是连接加载)
    • When you session.get() or session.load() the object that was previously selected and resides in cache. Cache is a storage where ID is the key and the properties are the values. So only when there is a possibility to search by ID you could eliminate hitting the DB.
    • When your associations are lazy-loaded (or eager-loaded with selects instead of joins)

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

    But it doesn't work when:

    • 如果您不按 ID 选择.再次 - 二级缓存存储实体 ID 到其他属性的映射(它实际上并不存储对象,而是存储数据本身),因此如果您的查找如下所示:from Authors where name = :name,那么你就不会点击缓存.
    • 当您使用 HQL 时(即使您使用 where id = ?).
    • 如果在您的映射中设置了 fetch="join",这意味着加载关联连接将在任何地方使用,而不是单独的选择语句.仅当使用 fetch="select" 时,进程级缓存才适用于子对象.
    • 即使您有 fetch="select" 但在 HQL 中您使用连接来选择关联 - 这些连接将立即发出,它们将覆盖您在 hbm.xml 或注释中指定的任何内容.
    • If you don't select by ID. Again - 2nd level cache stores a map of entities' IDs to other properties (it doesn't actually store objects, but the data itself), so if your lookup looks like this: from Authors where name = :name, then you don't hit cache.
    • When you use HQL (even if you use where id = ?).
    • If in your mapping you set fetch="join", this means that to load associations joins will be used everywhere instead of separate select statements. Process level cache works on children objects only if fetch="select" is used.
    • Even if you have fetch="select" but then in HQL you use joins to select associations - those joins will be issued right away and they will overwrite whatever you specified in hbm.xml or annotations.

    现在,关于查询缓存.您应该注意它不是一个单独的缓存,它是对进程级缓存的补充.假设您有一个 Country 实体.它是静态的,所以你知道每次当你说 from Country 时都会有相同的结果集.这是查询缓存的完美候选者,它本身会存储一个 ID 列表,当您下次选择所有国家/地区时,它将将此列表返回给进程级缓存,后者依次返回, 将返回每个 ID 的对象,因为这些对象已经存储在二级缓存中.每次与实体相关的任何更改时,查询缓存都会失效.因此,假设您将 from Authors 配置为放入查询缓存中.由于作者经常更改,它不会有效.所以你应该只对或多或少的静态数据使用查询缓存.

    Now, about Query Cache. You should note that it's not a separate cache, it's an addition to the process level cache. Let's say you have a Country entity. It's static, so you know that each time there will be the same result set when you say from Country. This is a perfect candidate for query cache, it will store a list of IDs in itself and when you next time select all countries, it will return this list to the process level cache and the latter, in turn, will return objects for each ID as these objects are stored already in the 2nd level cache. Query cache is invalidated each time anything related to the entity changes. So let's say you configured from Authors to be placed into a Query Cache. It won't be effective as Author changes often. So you should use Query Cache only for more or less static data.

    这篇关于何时以及如何使用休眠二级缓存?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆