Skip to content

在 nest 中使用 redis ​

前言 ​

一般在后端业务开发中,不可避免的肯定是要用 redis 的,比如缓存,比如消息队列等等。

那么 redis 的作用是什么?在 nest 中如何使用 redis 呢?本文将会介绍如何在 nest 中使用 redis。

为什么要用 redis ​

在后端业务的数据存储中,一般大多是使用 mysql 数据库来进行数据存储。但是 mysql 的数据是存在硬盘中的,而硬盘的读写速度是比较慢的

所以在一些对性能要求比较高的场景下,就需要使用 redis 来进行数据存储了。

因为 redis 是把数据存储在内存中的,如果程序直接从内存中读取数据,那么速度肯定是比从硬盘中读取数据要快的。

如何使用 redis ​

redis 被设计为 key value 的方式。而且 redis 的数据类型也比较丰富,也提供了很多的操作命令。

初步使用 redis,先使用 docker 起一个 redis 容器,然后使用 redis-cli 连接到 redis 容器中,然后就可以使用 redis 的命令了。

windows 下面启动 redis ​

下载 ​

ts
https://github.com/MSOpenTech/redis/releases

启动 redis ​

  • cd 到 redis 那个安装目录下,然后执行命令

这里一定要注意 你要是上面设置的端口号是 6380

那你就要去 redis.windows.conf 文件里找到 6379 替换成 6380

bash
redis-server.exe redis.windows.conf

测试 ​

  • 新开一个 cmd 窗口,然后进入到你那个安装目录下面
bash
redis-cli.exe -h 127.0.0.1 -p 6380

redis 命令 ​

ts
# 查看所有key
keys *
# 查看key的类型
type key
# 删除key
del key
# 设置key
set key value
# 获取key
get key
# 设置key的过期时间
expire key seconds
# 查看key的过期时间
ttl key
# 查看key是否存在
exists key

简单数据类型 ​

set/get ​

set 命令用来设置 key value,如果 key 不存在,则创建 key,如果 key 存在,则覆盖 key 的 value。

get 命令用来获取对应 key 的 value,如果 key 不存在,则返回 nil。

incr ​

incr 命令用来对 key 的 value 进行自增操作,如果 key 不存在,则创建 key,如果 key 存在,则对 key 的 value 进行自增操作。

decr ​

decr 命令用来对 key 的 value 进行自减操作,如果 key 不存在,则创建 key,如果 key 存在,则对 key 的 value 进行自减操作。

del ​

del 命令用来删除 key。

keys ​

keys 命令用来获取所有的 key。要带一个查询条件,比如*,表示获取所有的 key。

list 数据类型 ​

list 数据类型是一个有序的字符串链表,可以在链表的头部或者尾部插入数据,也可以在链表的头部或者尾部删除数据。

lpush ​

lpush 命令用来在链表的头部插入数据,如果链表不存在,则创建链表。

rpush ​

rpush 命令用来在链表的尾部插入数据。

lpop ​

lpop 命令用来在链表的头部删除数据。

rpop ​

rpop 命令用来在链表的尾部删除数据。

set 数据类型 ​

set 数据类型是一个无序的字符串集合,可以添加,删除,查看集合中的元素。

sadd ​

sadd 命令用来向集合中添加元素。而且相同的元素不会重复添加。

sismember ​

sismember 命令用来判断集合中是否存在某个元素。

ZSET 数据类型 ​

zset 数据类型是一个有序的字符串集合,可以添加,删除,查看集合中的元素。但是 zset 数据类型中的元素是有序的,而且每个元素都有一个分数,可以根据分数进行排序。

zadd ​

zrange ​

zrange 命令用来获取集合中的元素,可以根据分数进行排序。

zrevrank ​

zrevrank 命令用来获取集合中某个元素的倒序排名。

hash 数据类型 ​

hash 数据类型是一个无序的字符串集合,可以添加,删除,查看集合中的元素。但是 hash 数据类型中的元素是无序的。

hest ​

hset 命令用来向集合中添加元素。而且相同的元素不会重复添加。

hget ​

hget 命令用来获取集合中的元素。

expire 设置过期时间 ​

expire 命令用来设置 key 的过期时间。然后使用 ttl 命令来查看 key 的过期时间。

在 nest 种使用 redis ​

上面在 redis 的命令行中使用 redis-cli 简单体验了下 redis 的命令,接下来就在 nest 中使用 redis。

一般使用最流行的 redis 库就是 redis、ioredis。来看下每种库的使用方式。

安装 redis ​

ts
npm install redis --save

使用 redis 类库 ​

ts
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { createClient } from "redis";

@Module({
  imports: [],
  controllers: [AppController],
  providers: [
    AppService,
    {
      provide: "REDIS_CLIENT",
      async useFactory() {
        const client = createClient({
          socket: {
            host: "localhost",
            port: 6379,
          },
        });
        await client.connect();
        return client;
      },
    },
  ],
})
export class AppModule {}

然后就是在 service 种使用 redis 库了

ts
import { Inject, Injectable } from "@nestjs/common";
import { RedisClientType } from "redis";

@Injectable()
export class AppService {
  @Inject("REDIS_CLIENT")
  private redisClient: RedisClientType;

  async getHello() {
    const value = await this.redisClient.keys("*");
    console.log(value);

    return "Hello World!";
  }
}

ioredis ​

安装 ioredis 类库 ​

ts
npm install ioredis --save

创建一个全局模块 redis ​

  • 代码
ts
nest g resource redis

修改这个模块 ​

  • (1) 删除控制器 redis.controller.ts

  • (2) 修改 redis.module.ts

ts
import { Module, Global } from "@nestjs/common";
import { RedisService } from "./redis.service";

@Global()
@Module({
  controllers: [],
  providers: [RedisService],
  exports: [RedisService],
})
export class RedisModule {}
  • (3) 修改 redis.service.ts
ts
import { Inject, Injectable } from "@nestjs/common";
import { Redis } from "ioredis";
import { ConfigService } from "@nestjs/config";
@Injectable()
export class RedisService {
  // 定义
  private readonly redis: Redis;
  constructor(private readonly configServiceAll: ConfigService) {
    this.redis = new Redis({
      host: this.configServiceAll.get("redis").host, // 主机
      port: this.configServiceAll.get("redis").port, // 端口
      password: this.configServiceAll.get("redis").password, // 密码
      db: this.configServiceAll.get("redis").db, // 数据库
      family: 4, // IPV4||IPV6
    });
  }
  // 查询
  async get(key: string): Promise<string | null> {
    return await this.redis.get(key);
  }
  // 设置
  async set(key: string, value: any, expiration?: number): Promise<void> {
    if (expiration) {
      await this.redis.set(key, value, "EX", expiration);
    } else {
      await this.redis.set(key, value);
    }
  }
  // 设置列表
  async setList(key: string, list: Array<string>, ttl?: number): Promise<void> {
    for (let i = 0; i < list.length; i++) {
      await this.redis.lpush(key, list[i]);
    }
    if (ttl) {
      await this.redis.expire(key, ttl);
    }
  }
  // 获取列表
  async getList(key: string) {
    return await this.redis.lrange(key, 0, -1);
  }
}

使用 ​

  • 在其他模块下面的 service 中使用
ts
import { Injectable } from "@nestjs/common";

import { RedisService } from "../redis/redis.service";
@Injectable()
export class TestredisService {
  constructor(private readonly redisService: RedisService) {}

  async findAll() {
    // 插入
    await this.redisService.set("name", "张三");
    // 查询
    const name = await this.redisService.get("name");
    console.log(name);
    // 插入过期时间 单位秒
    await this.redisService.set("age", 18, 60);
    return name;
  }
}