如何在 NestJs 的 Typeorm 缓存配置中重用 Redis 连接
How to reuse Redis connection inside Typeorm cache config in NestJs
我正在使用 Redis 在 TypeOrm 中缓存查询。
但问题是,TypeOrm 和 Redis 包正在打开单独的连接,我只想为两者重用相同的连接。
这是 typeorm 配置:
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { Constants } from '../utils/Constants';
export const typeOrmConfig: TypeOrmModuleOptions = {
type: Constants.DB_TYPE,
host: Constants.DB_HOST,
port: Constants.DB_PORT,
username: Constants.DB_USER_NAME,
password: Constants.DB_PASSWORD,
database: Constants.DB_NAME,
entities: [ __dirname + '/../**/*.entity.{js,ts}' ],
synchronize: true,
logging: true,
cache: {
type: 'ioredis',
duration: 60000,
options: {
host: 'localhost',
password: 'swapnil',
port: 6379
}
},
extra: {
max: 10,
connectionTimeoutMillis: 2000
}
};
我正在为 Redis 使用 @svtslv/nestjs-ioredis 包:
import { Constants } from '../utils/Constants';
export const config = {
host: Constants.REDIS_HOST,
port: parseInt(Constants.REDIS_PORT),
db: parseInt(Constants.REDIS_DB),
password: Constants.REDIS_PASSWORD
};
并且使用这个包,我能够在我的服务中访问 redis class 使用:
public constructor(@InjectRedis() private readonly redis: Redis,) {}
在对 TypeORM 代码库进行一些挖掘之后,我遇到了两个解决方案(一个有点老套,而且我的案例有问题)
ORM 自定义查询结果缓存
根据文档,您可以实现自己的缓存处理程序,请参阅:https://github.com/typeorm/typeorm/blob/master/docs/caching.md。
由于需要实现接口,这是更好但更难的解决方案https://github.com/typeorm/typeorm/blob/master/src/cache/QueryResultCache.ts
此外,您需要使用 forRootAsync 注册 TypeOrmModule 才能首先连接到 Redis。
Hacky 欢乐时光
根据代码库,您应该能够访问 TypeORM 正在创建的 Redise 客户端(连接)。
在类型 ORM connection
上有一个名为 connection.queryResultCache
的成员用于管理缓存。
但是在 queryResultCache (connection.queryResultCache.client
)
上还有一个成员名称 client
参见 TypeORM redis 缓存说明:
https://github.com/typeorm/typeorm/blob/master/src/cache/RedisQueryResultCache.ts
import { Connection } from 'typeorm';
@Module({
imports: [TypeOrmModule.forRoot()],
})
export class AppModule {
constructor(private connection: Connection) {
connection.queryResultCache.client // <-- Cache client.
}
}
但不用说,这不是预期用途,这会将您的数据库与 Redis 耦合,这对于 future-proofing 您的代码库来说并不合适。
我的诚实意见
根据 关注点分离 的想法,我建议坚持使用两个连接而不是一个连接,只是为了保持 DB query Cache
和标准 Cache
分开了。
这将使您在未来进行集成测试和重构时更加灵活。
我正在使用 Redis 在 TypeOrm 中缓存查询。
但问题是,TypeOrm 和 Redis 包正在打开单独的连接,我只想为两者重用相同的连接。
这是 typeorm 配置:
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { Constants } from '../utils/Constants';
export const typeOrmConfig: TypeOrmModuleOptions = {
type: Constants.DB_TYPE,
host: Constants.DB_HOST,
port: Constants.DB_PORT,
username: Constants.DB_USER_NAME,
password: Constants.DB_PASSWORD,
database: Constants.DB_NAME,
entities: [ __dirname + '/../**/*.entity.{js,ts}' ],
synchronize: true,
logging: true,
cache: {
type: 'ioredis',
duration: 60000,
options: {
host: 'localhost',
password: 'swapnil',
port: 6379
}
},
extra: {
max: 10,
connectionTimeoutMillis: 2000
}
};
我正在为 Redis 使用 @svtslv/nestjs-ioredis 包:
import { Constants } from '../utils/Constants';
export const config = {
host: Constants.REDIS_HOST,
port: parseInt(Constants.REDIS_PORT),
db: parseInt(Constants.REDIS_DB),
password: Constants.REDIS_PASSWORD
};
并且使用这个包,我能够在我的服务中访问 redis class 使用:
public constructor(@InjectRedis() private readonly redis: Redis,) {}
在对 TypeORM 代码库进行一些挖掘之后,我遇到了两个解决方案(一个有点老套,而且我的案例有问题)
ORM 自定义查询结果缓存
根据文档,您可以实现自己的缓存处理程序,请参阅:https://github.com/typeorm/typeorm/blob/master/docs/caching.md。
由于需要实现接口,这是更好但更难的解决方案https://github.com/typeorm/typeorm/blob/master/src/cache/QueryResultCache.ts
此外,您需要使用 forRootAsync 注册 TypeOrmModule 才能首先连接到 Redis。
Hacky 欢乐时光
根据代码库,您应该能够访问 TypeORM 正在创建的 Redise 客户端(连接)。
在类型 ORM connection
上有一个名为 connection.queryResultCache
的成员用于管理缓存。
但是在 queryResultCache (connection.queryResultCache.client
)
client
参见 TypeORM redis 缓存说明: https://github.com/typeorm/typeorm/blob/master/src/cache/RedisQueryResultCache.ts
import { Connection } from 'typeorm';
@Module({
imports: [TypeOrmModule.forRoot()],
})
export class AppModule {
constructor(private connection: Connection) {
connection.queryResultCache.client // <-- Cache client.
}
}
但不用说,这不是预期用途,这会将您的数据库与 Redis 耦合,这对于 future-proofing 您的代码库来说并不合适。
我的诚实意见
根据 关注点分离 的想法,我建议坚持使用两个连接而不是一个连接,只是为了保持 DB query Cache
和标准 Cache
分开了。
这将使您在未来进行集成测试和重构时更加灵活。