缓存查询

你可以缓存getManygetOnegetRawManygetRawOnegetCount这些QueryBuilder方法的查询结果。

还可以缓存findfindAndCountfindByIdscount这些Repository方法查询的结果。

要启用缓存,需要在连接选项中明确启用它:

  1. {
  2. type: "mysql",
  3. host: "localhost",
  4. username: "test",
  5. ...
  6. cache: true
  7. }

首次启用缓存时,你必须同步数据库架构(使用 CLI,migrations 或synchronize连接选项)。

然后在QueryBuilder中,你可以为任何查询启用查询缓存:

  1. const users = await connection
  2. .createQueryBuilder(User, "user")
  3. .where("user.isAdmin = :isAdmin", { isAdmin: true })
  4. .cache(true)
  5. .getMany();

等同于Repository查询:

  1. const users = await connection.getRepository(User).find({
  2. where: { isAdmin: true },
  3. cache: true
  4. });

这将执行查询以获取所有 admin users 并缓存结果。下次执行相同的代码时,它将从缓存中获取所有 admin users。默认缓存生存期为1000 ms,例如 1 秒。这意味着在调用查询构建器代码后 1 秒内缓存将无效。实际上,这也意味着如果用户在 3 秒内打开用户页面 150 次,则在此期间只会执行三次查询。在 1 秒缓存窗口期间插入的任何 users 都不会返回到 user。

你可以通过QueryBuilder手动更改缓存时间:

  1. const users = await connection
  2. .createQueryBuilder(User, "user")
  3. .where("user.isAdmin = :isAdmin", { isAdmin: true })
  4. .cache(60000) // 1 分钟
  5. .getMany();

或者通过 Repository:

  1. const users = await connection.getRepository(User).find({
  2. where: { isAdmin: true },
  3. cache: 60000
  4. });

或者通过全局连接选项:

  1. {
  2. type: "mysql",
  3. host: "localhost",
  4. username: "test",
  5. ...
  6. cache: {
  7. duration: 30000 // 30 seconds
  8. }
  9. }

此外,你可以通过QueryBuilder设置”cache id”:

  1. const users = await connection
  2. .createQueryBuilder(User, "user")
  3. .where("user.isAdmin = :isAdmin", { isAdmin: true })
  4. .cache("users_admins", 25000)
  5. .getMany();

或者通过 Repository:

  1. const users = await connection.getRepository(User).find({
  2. where: { isAdmin: true },
  3. cache: {
  4. id: "users_admins",
  5. milisseconds: 25000
  6. }
  7. });

这使你可以精确控制缓存,例如,在插入新用户时清除缓存的结果:

  1. await connection.queryResultCache.remove(["users_admins"]);

默认情况下,TypeORM 使用一个名为query-result-cache的单独表,并在那里存储所有查询和结果。表名是可配置的,因此您可以通过在 tableName 属性中给出值来更改它例如:

  1. {
  2. type: "mysql",
  3. host: "localhost",
  4. username: "test",
  5. ...
  6. cache: {
  7. type: "database",
  8. tableName: "configurable-table-query-result-cache"
  9. }
  10. }

如果在单个数据库表中存储缓存对你无效,则可以将缓存类型更改为”redis”或者”ioredis”,而 TypeORM 将以 redis 形式存储所有缓存的记录。例如:

  1. {
  2. type: "mysql",
  3. host: "localhost",
  4. username: "test",
  5. ...
  6. cache: {
  7. type: "redis",
  8. options: {
  9. host: "localhost",
  10. port: 6379
  11. }
  12. }
  13. }

“options” 可以是node_redis specific options 或者ioredis specific options,具体取决于你使用的类型。

如果你想使用IORedis的集群功能连接到redis-cluster,则可以通过方式下操作来执行此操作:

  1. {
  2. type: "mysql",
  3. host: "localhost",
  4. username: "test",
  5. cache: {
  6. type: "ioredis/cluster",
  7. options: {
  8. startupNodes: [
  9. {
  10. host: 'localhost',
  11. port: 7000,
  12. },
  13. {
  14. host: 'localhost',
  15. port: 7001,
  16. },
  17. {
  18. host: 'localhost',
  19. port: 7002,
  20. }
  21. ],
  22. options: {
  23. scaleReads: 'all',
  24. clusterRetryStrategy: function (times) { return null },
  25. redisOptions: {
  26. maxRetriesPerRequest: 1
  27. }
  28. }
  29. }
  30. }
  31. }

请注意,你仍然可以使用选项作为IORedis的集群构造函数的第一个参数。

  1. {
  2. ...
  3. cache: {
  4. type: "ioredis/cluster",
  5. options: [
  6. {
  7. host: 'localhost',
  8. port: 7000,
  9. },
  10. {
  11. host: 'localhost',
  12. port: 7001,
  13. },
  14. {
  15. host: 'localhost',
  16. port: 7002,
  17. }
  18. ]
  19. },
  20. ...
  21. }

你可以使用typeorm cache:clear来清除存储在缓存中的所有内容。