• 缓存查询

    缓存查询

    你可以缓存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来清除存储在缓存中的所有内容。