查询缓存
本页面由 PageTurner AI 翻译(测试版)。未经项目官方认可。 发现错误? 报告问题 →
你可以缓存通过 QueryBuilder 方法 getMany、getOne、getRawMany、getRawOne 和 getCount 选择的结果。
你也可以缓存通过 Repository 和 EntityManager 的 find* 和 count* 方法选择的结果。
要启用缓存,你需要在数据源选项中显式开启:
{
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 秒后缓存将失效。
实践中,如果用户在 3 秒内打开用户页面 150 次,此期间只会执行三次查询。
在 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 设置 "缓存 ID":
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",TypeORM 会将缓存记录存储在 Redis 中:
{
type: "mysql",
host: "localhost",
username: "test",
...
cache: {
type: "redis",
options: {
socket: {
host: "localhost",
port: 6379
}
}
}
}
"options" 可以是 node_redis 特定配置 或 ioredis 特定配置,具体取决于使用类型。
如需通过 IORedis 的集群功能连接 Redis 集群,可如下操作:
{
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
}
}
}
}
}
注意:你仍可将 options 作为 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 命令清除缓存中的所有内容。