Ответ
Кэширование в ORM минимизирует обращения к базе данных, сохраняя загруженные сущности и результаты запросов в памяти.
Основные преимущества:
- Резкое повышение производительности для операций чтения, особенно при повторных обращениях к одним и тем же данным.
- Снижение нагрузки на СУБД за счет сокращения количества выполняемых SQL-запросов.
- Обеспечение консистентности в рамках сессии (кэш первого уровня).
Уровни кэширования в Hibernate:
| Уровень | Область видимости | Назначение |
|---|---|---|
| Кэш 1-го уровня (L1) | Сессия (Session) |
Автоматический. Гарантирует, что в рамках одной сессии загрузка сущности по идентификатору всегда возвращает один и тот же экземпляр объекта. |
| Кэш 2-го уровня (L2) | Фабрика сессий (SessionFactory) |
Опциональный, общий для всех сессий. Требует явного включения и провайдера (Ehcache, Infinispan, Redis). |
| Кэш запросов | Фабрика сессий (SessionFactory) |
Кэширует результаты часто выполняемых HQL/JPA-запросов или критериев. Работает только при включенном L2-кэше. |
Пример настройки L2-кэша для сущности:
@Entity
@Cacheable // Активация кэширования для JPA
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) // Стратегия Hibernate
public class Product {
@Id
private Long id;
private String name;
}
Важные аспекты:
- Стратегии согласованности:
READ_ONLY(только для неизменяемых данных),READ_WRITE,NONSTRICT_READ_WRITE,TRANSACTIONAL. - Инвалидация кэша – критически важна при изменении данных через другие приложения или прямые SQL-запросы. Требует настройки стратегий обновления или явного сброса.
Ответ 18+ 🔞
Да ты посмотри, какие штуки придумали, чтобы базу данных не ебашить почём зря! Кэширование в ORM — это типа такой хитрожопый способ не лазить в базу каждый раз, как дурак, а держать уже загруженные штуки прямо в памяти.
Что за плюсы, спросишь? Да овердохуищные:
- Скорость пиздец как растёт, особенно если ты тупо раз за разом лезешь за одними и теми же данными.
- База не обоссытся от запросов — нагрузка падает, потому что SQL-запросов становится меньше.
- В рамках одной сессии всё чётко — кэш первого уровня следит, чтобы один и тот же объект тебе и возвращался.
А уровни кэширования в Hibernate, блядь, вот какие бывают:
| Уровень | Где живёт | Зачем нужен |
|---|---|---|
| Кэш 1-го уровня (L1) | Внутри сессии (Session) |
Работает сам, автоматом. Чтобы если ты в одной сессии дважды за одной хуйней полез, тебе один и тот же экземпляр вернули, а не два разных. |
| Кэш 2-го уровня (L2) | На всю фабрику сессий (SessionFactory) |
Вот это уже поинтереснее. Общий для всех. Но его надо специально включать и какую-нибудь библиотеку-провайдер подсовывать (Ehcache, Infinispan, Redis). |
| Кэш запросов | Тоже на фабрике (SessionFactory) |
Запоминает результаты твоих частых HQL-запросов. Но, внимание, ёпта, работает только если L2-кэш тоже включён! |
Вот как, например, сущность пометить, чтобы её в L2-кэш пихали:
@Entity
@Cacheable // Говорим JPA: "Кэшируй это, блядь"
@org.hibernate.annotations.Cache(usage = CacheConcurrencyStrategy.READ_WRITE) // А это Hibernate-у, со стратегией
public class Product {
@Id
private Long id;
private String name;
}
А теперь, чувак, главное не обосраться:
- Стратегии, блядь, выбери с умом:
READ_ONLY(только для того, что не меняется),READ_WRITE,NONSTRICT_READ_WRITE,TRANSACTIONAL. Каждая — под свой случай. - Инвалидация кэша — вот где собака зарыта! Если данные меняются через другое приложение или прямой SQL-запрос, а кэш про это не знает — будет пиздец и рассинхрон. Надо либо стратегии правильно настраивать, либо кэш вручную сбрасывать. Иначе получишь старые данные, а потом будешь чесать репу, где ж ошибка.