Кэширование запросов
Эта страница переведена PageTurner AI (бета). Не одобрена официально проектом. Нашли ошибку? Сообщить о проблеме →
Вы можете кэшировать результаты, полученные через методы QueryBuilder: getMany, getOne, getRawMany, getRawOne и getCount.
Кэшировани е также доступно для результатов методов find* и count* в Repository и EntityManager.
Для активации кэширования необходимо явно включить его в настройках источника данных:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: true
}
При первом включении кэша
вам потребуется синхронизировать схему базы данных (через CLI, миграции или опцию synchronize источника данных).
Затем в QueryBuilder можно активировать кэш для любого запроса:
const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache(true)
.getMany()
Эквивалентный запрос через Repository:
const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: true,
})
Это выполнит запрос для получения всех администраторов и закэширует результаты.
При следующем запуске этого же кода данные будут взяты из кэша.
Стандартное время жизни кэша — 1000 ms (1 секунда).
Это означает, что кэш станет недействительным через 1 секунду после вызова кода QueryBuilder.
На практике: если пользователи откроют страницу 150 раз за 3 секунды, будет выполнено всего 3 запроса.
Пользователи, добавленные в течение 1-секундного окна кэширования, не будут отображены.
Время кэширования можно изменить вручную через QueryBuilder:
const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache(60000) // 1 minute
.getMany()
Через Repository:
const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: 60000,
})
Или глобально в настройках источника данных:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
duration: 30000 // 30 seconds
}
}
Также можно задать "идентификатор кэша" через QueryBuilder:
const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache("users_admins", 25000)
.getMany()
Или через Repository:
const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: {
id: "users_admins",
milliseconds: 25000,
},
})
Это обеспечивает детальный контроль над кэшем,
например, очистку кэша при добавлении нового пользователя:
await dataSource.queryResultCache.remove(["users_admins"])
По умолчанию TypeORM использует отдельную таблицу query-result-cache для хранения запросов и результатов.
Имя таблицы настраивается через свойство tableName:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "database",
tableName: "configurable-table-query-result-cache"
}
}
Если хранение кэша в таблице БД неэффективно,
можно переключиться на "redis" или "ioredis" для хранения записей в Redis:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "redis",
options: {
socket: {
host: "localhost",
port: 6379
}
}
}
}
Параметр "options" может содержать специфичные настройки node_redis или настройки ioredis в зависимости от типа.
Для подключения к redis-cluster через кластерную функциональность IORedis:
{
type: "mysql",
host: "localhost",
username: "test",
cache: {
type: "ioredis/cluster",
options: {
startupNodes: [
{
host: 'localhost',
port: 7000,
},
{
host: 'localhost',
port: 7001,
},
{
host: 'localhost',
port: 7002,
}
],
options: {
scaleReads: 'all',
clusterRetryStrategy: function (times) { return null },
redisOptions: {
maxRetriesPerRequest: 1
}
}
}
}
}
Примечание: вы можете передавать параметры первым аргументом в конструктор кластера IORedis.
{
...
cache: {
type: "ioredis/cluster",
options: [
{
host: 'localhost',
port: 7000,
},
{
host: 'localhost',
port: 7001,
},
{
host: 'localhost',
port: 7002,
}
]
},
...
}
Если стандартные провайдеры кэша не подходят,
можно создать кастомный провайдер через фабричную функцию provider,
возвращающую объект с интерфейсом QueryResultCache:
class CustomQueryResultCache implements QueryResultCache {
constructor(private dataSource: DataSource) {}
...
}
{
...
cache: {
provider(dataSource) {
return new CustomQueryResultCache(dataSource);
}
}
}
Для игнорирования ошибок кэша и передачи запросов напрямую в БД используйте опцию ignoreErrors:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "redis",
options: {
socket: {
host: "localhost",
port: 6379
}
},
ignoreErrors: true
}
}
Для полной очистки кэша выполните: typeorm cache:clear.