安装MySQL及相关依赖
下载dmg文件安装
前往MySQL :: Download MySQL Community Server下载最新版本的MySQL。
打开系统设置,拉到最下方可以看到MySQL,打开看到两个绿点表示安装成功,也可以在这里修改MySQL密码。
配置环境变量
打开终端配置MySQL环境:
vim ~/.bash_profile
按字母 i 键切换至输入状态,添加如下配置:
export PATH=${PATH}:/usr/local/mysql/bin
按ESC键退出输入状态,输入:wq回车即可,然后执行 source ~/.bash_profile 使其配置生效。为确保配置成功,vim ~/.zshrc 按以上步骤操作一遍。
输入mysql --version,出现MySQL版本信息,则表示配置成功。
进入MySQL
终端输入 mysql -u root -p 回车输入数据库密码,出现如下信息说明进入MySQL成功。
安装MySQL可视化工具(可选)
MySQL Workbench 官方地址:https://dev.mysql.com/downloads/workbench/。或者使用一个 VSCode 数据库可视化插件Database Client
,安装完后连接我们的数据库就能进行一个可视化操作。先需要使用账号密码连接MySQL,然后创建一个数据库ADMIN,然后可以手动创建表或者选择导入sql文件,也可以通过后面的实体文件自动创建。最终效果如下:
安装相关依赖
安装typeorm及mysql2等相关依赖,typeorm
可以将数据库的 sql 操作转化为对象操作:
npm install --save @nestjs/typeorm typeorm mysql2
项目配置
来到app.module.ts
中进行数据库的配置,引入TypeOrmModule
调用forRoot
进行配置。
javascript
import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { UserModule } from "./user/user.module";
import { TypeOrmModule } from "@nestjs/typeorm";
@Module({
imports: [
TypeOrmModule.forRoot({
type: "mysql",
synchronize: true,
autoLoadEntities: true, //自动加载实体
host: "localhost",
port: 3306, // 端口号
username: "root", // 用户名
password: "root", // 密码
database: "admin", //数据库名
synchronize: true, //是否自动同步实体文件,生产环境建议关闭
}),
UserModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
当我们将autoLoadEntities
设置为 true 的时候,NestJS 会自动加载数据库实体文件xx.entity.ts
文件来创建数据表(如果没有的话),比如 user/entities/user.entity.ts,我们简单加一些字段:
javascript
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity("user")
export class User {
@PrimaryGeneratedColumn("uuid")
id: number; // 标记为主键,值自动生成
@Column({ length: 30 })
username: string; //用户名
@Column()
password: string; //密码
}
启动项目,然后就会发现自动创建了一个 user 表。
到此为止,mysql和typeorm配置相关内容就完成了。下面进入Redis的编译和使用。
Redis使用
下载Redis源码并编译
前往Download | Redis下载Redis源码,解压后使用make命令进行编译。make成功后会在src文件夹下产生一些二进制可执行文件,包括redis-server、redis-cli等等:
bash
$ find . -type f -executable
./redis-benchmark //用于进行redis性能测试的工具
./redis-check-dump //用于修复出问题的dump.rdb文件
./redis-cli //redis的客户端
./redis-server //redis的服务端
./redis-check-aof //用于修复出问题的AOF文件
./redis-sentinel //用于集群管理
启动redis
启动redis非常简单,进入到Redis源码的src目录,直接./redis-server就可以启动服务端了,还可以用下面的方法指定要加载的配置文件:
./redis-server ../redis.conf
默认情况下,redis-server会以非daemon的方式来运行,且默认服务端口为6379。
使用redis客户端
我们直接看一个使用redis-cli启动redis客户端的例子:
$ ./redis-cli
//用set指令来设置key、value
127.0.0.1:6379> set name "roc"
OK
//来获取name的值
127.0.0.1:6379> get name
"roc"
//通过客户端来关闭redis服务端
127.0.0.1:6379> shutdown
127.0.0.1:6379>
Redis可视化插件
我们使用命令行想查看redis中的数据不太方便,所以我们需要一个可视化插件,前面文章已经提到过,安装一个将Database Client的插件,它可以将数据库可视化,同时也可以连接redis。
安装相关依赖
使用代码来操作redis需要安装Redis库,因nest.js官方推荐的redis库年久失修,考虑社区活跃度和稳定性选择@liaoliaots/nestjs-redis和ioredis:
javascript
npm install @liaoliaots/nestjs-redis ioredis
由于@liaoliaots/nestjs-redis依赖的nest.js组件版本过旧,npm install的时候会失败,需要在package.json中增加:
javascript
"overrides": {
"@liaoliaots/nestjs-redis": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0"
},
},
项目配置
一般我们会给对 redis 的操作单独建一个模块,后面有哪些模块需要使用 redis 直接引入这个模块即可,这里我们将模块命名为 cache,使用 nestcli 命令创建。
在service中我们实现一些常用的Redis操作:
javascript
import { InjectRedis } from '@liaoliaots/nestjs-redis'
import { Injectable } from '@nestjs/common'
import Redis from 'ioredis'
@Injectable()
export class CacheService {
constructor(@InjectRedis() private readonly client: Redis) { }
getClient(): Redis {
return this.client
}
/* --------------------- string 相关 -------------------------- */
/**
*
* @param key 存储 key 值
* @param val key 对应的 val
* @param seconds 可选,过期时间,单位 秒
*/
async set(key: string, val: string, seconds?: number): Promise<'OK' | null> {
if (!seconds) return await this.client.set(key, val)
return await this.client.set(key, val, 'EX', seconds)
}
/**
* 返回对应 value
* @param key
*/
async get(key: string): Promise<string | null> {
if (!key || key === '*') return null
return await this.client.get(key)
}
async del(keys: string | string[]): Promise<number> {
if (!keys || keys === '*') return 0
if (typeof keys === 'string') keys = [keys]
return await this.client.del(...keys)
}
}
@Global()
装饰器使模块具有全局作用域。CacheModule的CacheService将无处不在,希望注入CacheService的模块将不需要在其导入数组中导入 CacheModule。同时为了注册经过配置的RedisModule,这里使用动态模块来创建自定义的模块,这个模块可以动态注册和配置provider:
javascript
import { Module, Global, DynamicModule } from '@nestjs/common';
import { CacheService } from './cache.service';
import { RedisModule, RedisModuleAsyncOptions, RedisModuleOptions } from '@liaoliaots/nestjs-redis'
@Global()
@Module({
exports: [CacheService],
providers: [CacheService],
})
export class CacheModule {
static forRoot(options: RedisModuleOptions, isGlobal = true): DynamicModule {
return {
module: CacheModule,
imports: [RedisModule.forRoot(options, isGlobal)],
providers: [CacheService],
exports: [CacheService]
}
}
static forRootAsync(options: RedisModuleAsyncOptions, isGlobal = true): DynamicModule {
return {
module: CacheModule,
imports: [RedisModule.forRootAsync(options, isGlobal)],
providers: [CacheService],
exports: [CacheService]
}
}
}