Cache delle query
Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →
Puoi memorizzare nella cache i risultati selezionati con questi metodi di QueryBuilder: getMany, getOne, getRawMany, getRawOne e getCount.
Puoi anche memorizzare nella cache i risultati selezionati dai metodi find* e count* di Repository ed EntityManager.
Per abilitare la cache, devi attivarla esplicitamente nelle opzioni della data source:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: true
}
Quando abiliti la cache per la prima volta,
devi sincronizzare lo schema del database (usando CLI, migrazioni o l'opzione synchronize della data source).
Poi in QueryBuilder puoi abilitare la cache per qualsiasi query:
const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache(true)
.getMany()
Query equivalente con Repository:
const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: true,
})
Questo eseguirà una query per recuperare tutti gli utenti admin e memorizzerà i risultati nella cache.
Alla successiva esecuzione dello stesso codice, gli utenti admin verranno recuperati dalla cache.
La durata predefinita della cache è pari a 1000 ms, cioè 1 secondo.
Ciò significa che la cache diventerà invalida 1 secondo dopo la chiamata del codice del query builder.
Nella pratica, se gli utenti aprono la pagina utente 150 volte in 3 secondi, verranno eseguite solo tre query in questo periodo.
Gli utenti inseriti durante la finestra di cache di 1 secondo non verranno restituiti.
Puoi modificare manualmente il tempo di cache tramite QueryBuilder:
const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache(60000) // 1 minute
.getMany()
O tramite Repository:
const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: 60000,
})
O globalmente nelle opzioni della data source:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
duration: 30000 // 30 seconds
}
}
Inoltre, puoi impostare un "cache id" tramite QueryBuilder:
const users = await dataSource
.createQueryBuilder(User, "user")
.where("user.isAdmin = :isAdmin", { isAdmin: true })
.cache("users_admins", 25000)
.getMany()
O con Repository:
const users = await dataSource.getRepository(User).find({
where: { isAdmin: true },
cache: {
id: "users_admins",
milliseconds: 25000,
},
})
Questo ti offre un controllo granulare della cache, ad esempio per cancellare i risultati memorizzati quando inserisci un nuovo utente:
await dataSource.queryResultCache.remove(["users_admins"])
Per impostazione predefinita, TypeORM utilizza una tabella separata chiamata query-result-cache per memorizzare query e risultati.
Il nome della tabella è configurabile modificando il valore della proprietà tableName:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "database",
tableName: "configurable-table-query-result-cache"
}
}
Se memorizzare la cache in una singola tabella non è efficace per te, puoi cambiare il tipo di cache in "redis" o "ioredis": TypeORM memorizzerà tutti i record in Redis. Esempio:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "redis",
options: {
socket: {
host: "localhost",
port: 6379
}
}
}
}
"options" può essere opzioni specifiche di node_redis o opzioni specifiche di ioredis a seconda del tipo utilizzato.
Se desideri connetterti a un cluster Redis usando la funzionalità cluster di IORedis, puoi farlo così:
{
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
}
}
}
}
}
Nota che puoi comunque usare le options come primo argomento del costruttore del cluster di IORedis.
{
...
cache: {
type: "ioredis/cluster",
options: [
{
host: 'localhost',
port: 7000,
},
{
host: 'localhost',
port: 7001,
},
{
host: 'localhost',
port: 7002,
}
]
},
...
}
Se nessun provider di cache integrato soddisfa le tue esigenze, puoi specificarne uno personalizzato usando una funzione factory provider che restituisca un nuovo oggetto implementante l'interfaccia QueryResultCache:
class CustomQueryResultCache implements QueryResultCache {
constructor(private dataSource: DataSource) {}
...
}
{
...
cache: {
provider(dataSource) {
return new CustomQueryResultCache(dataSource);
}
}
}
Se vuoi ignorare gli errori della cache e far passare le query al database in caso di errori, usa l'opzione ignoreErrors:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "redis",
options: {
socket: {
host: "localhost",
port: 6379
}
},
ignoreErrors: true
}
}
Puoi usare typeorm cache:clear per svuotare completamente la cache.