Ответ
В терминологии Hibernate не существует понятия "кэш третьего уровня" (L3 cache). Это распространённая путаница, возникающая из-за аналогии с архитектурой процессоров (L1/L2/L3).
Корректная терминология Hibernate:
- Кэш первого уровня (L1) / Кэш сессии: Привязан к объекту
Session. Включён всегда, жизненный цикл равен сессии. - Кэш второго уровня (L2): Общий кэш на уровне
SessionFactory, как описано в предыдущем ответе. - Кэш запросов (Query Cache): Отдельный кэш для результатов нативных и HQL-запросов. Часто ошибочно называют "L3". Он хранит не сущности, а идентификаторы и значения скалярных типов.
Пример настройки и использования кэша запросов:
// 1. Включение в конфигурации
// hibernate.cfg.xml: <property name="hibernate.cache.use_query_cache">true</property>
// 2. Указание кэшируемости в запросе
Session session = sessionFactory.openSession();
Query<Product> query = session.createQuery("from Product p where p.category = :cat", Product.class)
.setParameter("cat", "Electronics")
.setCacheable(true) // Ключевой момент!
.setCacheRegion("product.queries"); // Опционально: регион кэша
List<Product> products = query.getResultList(); // Результат кэшируется
session.close();
// При повторном выполнении того же запроса с теми же параметрами
// Hibernate возьмёт список ID из кэша запросов и загрузит сущности из L2/L1 кэша.
Почему кэш запросов используют осторожно:
- Он становится неактуальным при любом изменении таблиц, связанных с сущностями в запросе.
- Эффективен только для часто выполняемых и редко меняющихся запросов с фиксированными параметрами.
Ответ 18+ 🔞
Давай раз и навсегда разберёмся с этим вопросом, а то народ путается, как в тёмном лесу, блядь.
Слушай сюда, главное запомни: в Хибернейте нет никакого "кэша третьего уровня" (L3 cache), ёпта! Всё, точка. Это выдумка, миф, пиздёж собачий, который пошёл от каких-то умников, которые решили провести аналогию с процессорами (L1, L2, L3). Вот так вот, на хуй, взяли и запутали всех.
Как на самом деле, блядь:
-
Кэш первого уровня (L1) / Кэш сессии. Это твой личный, персональный кэш, привязанный к конкретной сессии (
Session). Он всегда включён, живёт ровно столько, сколько живёт сессия, и потом накрывается медным тазом. Как будто у тебя в кармане лежит записка — пока ты её не выкинул, она твоя. -
Кэш второго уровня (L2). Вот это уже серьёзно, блядь. Это общий кэш на всю фабрику сессий (
SessionFactory). Как общий холодильник на всю коммуналку — все туда могут заглянуть. Про него мы уже говорили. -
Кэш запросов (Query Cache). А вот это, сука, и есть тот самый "фантомный L3", о котором все трубят! Его так ошибочно называют. На самом деле он отдельный и хранит не сами сущности, а результаты запросов: списки идентификаторов и всякие скалярные значения. Представь, что ты записал, в каких магазинах был, но не записал, что именно купил.
Вот как этим пользоваться, на живом примере:
// 1. Сначала говоришь Хибернейту: "Хочу кэш запросов, сука!"
// В конфиге: <property name="hibernate.cache.use_query_cache">true</property>
// 2. Потом в коде, когда делаешь запрос, ты ему прямо указываешь:
Session session = sessionFactory.openSession();
Query<Product> query = session.createQuery("from Product p where p.category = :cat", Product.class)
.setParameter("cat", "Electronics")
.setCacheable(true) // Вот это, блядь, самый важный момент! Говоришь: "Кэшируй это!"
.setCacheRegion("product.queries"); // Можно ещё указать "полку", куда положить (опционально)
List<Product> products = query.getResultList(); // Первый раз выполнится и закэшируется
session.close();
// А теперь, охуеть, второй раз!
// Хибернейт не полезет в базу, а достанет из кэша запросов список IDшников,
// а сами сущности подтянет уже из L2 или L1 кэша, если они там есть.
Но, чувак, с этим кэшом запросов надо как с огнём, блядь! Осторожно!
Почему? Да потому что он ебаный максималист. Любое, малейшее изменение данных в таблицах, которые участвовали в запросе — и всё, пиздец, кэш устарел, надо инвалидировать. Он эффективен только для запросов, которые:
- Выполняются чаще, чем ты моргаешь.
- А данные в них меняются реже, чем президент в Северной Корее.
- И параметры запроса всегда одни и те же, как заезженная пластинка.
В общем, инструмент мощный, но если использовать его бездумно — можно получить овердохуища проблем с актуальностью данных. Думай головой, а не просто втыкай аннотации куда попало!