NestJS 中集成 MySQL 和 Redis 的完整指南

目录
简介
在现代化的 Web 应用中,数据库和缓存是必不可少的组件。本文将详细介绍如何在 NestJS 项目中集成 MySQL 和 Redis,包括配置、使用和最佳实践。
环境准备
在开始之前,请确保你的开发环境中已安装:
- Node.js (推荐 v16+)
- MySQL 8.0+
- Redis 7.0+
- Docker (可选,用于容器化部署)
MySQL 集成
安装依赖
首先,我们需要安装必要的依赖包:
bash
pnpm add @nestjs/typeorm typeorm mysql2
配置数据库连接
- 创建配置文件
src/config/configuration.ts
:
typescript
export default () => ({
database: {
host: process.env.DB_HOST || 'localhost',
port: parseInt(process.env.DB_PORT, 10) || 3306,
username: process.env.DB_USERNAME || 'root',
password: process.env.DB_PASSWORD || 'root',
database: process.env.DB_DATABASE || 'blog',
},
});
- 创建数据库配置模块
src/config/database.config.ts
:
typescript
import { TypeOrmModuleOptions } from '@nestjs/typeorm';
import { ConfigService } from '@nestjs/config';
export function getBaseDbConfig(configService: ConfigService) {
return {
type: 'mysql',
host: configService.get('database.host'),
port: configService.get('database.port'),
username: configService.get('database.username'),
password: configService.get('database.password'),
database: configService.get('database.database'),
timezone: '+08:00',
charset: 'utf8mb4',
logging: configService.get<boolean>('database.logging', false),
};
}
export const createTypeOrmOptions = async (
configService: ConfigService,
): Promise<TypeOrmModuleOptions> => {
const baseConfig = getBaseDbConfig(configService);
return {
...baseConfig,
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
synchronize: process.env.NODE_ENV === 'development',
};
};
创建实体
使用 TypeORM 装饰器创建实体类,例如用户实体:
typescript
import { Entity, Column } from 'typeorm';
import { BaseEntity } from './base.entity';
@Entity('t_user')
export class User extends BaseEntity {
@Column({ length: 50 })
nickname: string;
@Column({ length: 50, unique: true })
username: string;
@Column({ select: true })
password: string;
@Column({ nullable: true })
avatar: string;
}
使用 TypeORM
在模块中配置 TypeORM:
typescript
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { createTypeOrmOptions } from './config/database.config';
@Module({
imports: [
ConfigModule.forRoot({
load: [configuration],
}),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: createTypeOrmOptions,
inject: [ConfigService],
}),
],
})
export class AppModule {}
Redis 集成
安装依赖
bash
pnpm add ioredis
配置 Redis 服务
- 创建 Redis 服务
src/redis/redis.service.ts
:
typescript
import { Injectable, Logger, OnModuleDestroy, OnModuleInit } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import * as Redis from 'ioredis';
@Injectable()
export class RedisService implements OnModuleInit, OnModuleDestroy {
private readonly logger = new Logger(RedisService.name);
private redisClient: Redis.Redis;
constructor(private readonly configService: ConfigService) {}
async onModuleInit() {
try {
this.redisClient = new Redis.Redis({
host: this.configService.get('redis.host', 'localhost'),
port: this.configService.get('redis.port', 6379),
password: this.configService.get('redis.password', null),
db: this.configService.get('redis.db', 0),
retryStrategy: (times) => {
const delay = Math.min(times * 50, 2000);
return delay;
},
});
this.redisClient.on('connect', () => {
this.logger.log('Redis连接成功');
});
this.redisClient.on('error', (error) => {
this.logger.error(`Redis连接错误: ${error.message}`);
});
} catch (error) {
this.logger.error(`初始化Redis客户端失败: ${error.message}`);
}
}
async onModuleDestroy() {
await this.redisClient?.quit();
}
// Redis 操作方法
async set(key: string, value: any, ttl?: number): Promise<void> {
const stringValue = JSON.stringify(value);
if (ttl) {
await this.redisClient.setex(key, ttl, stringValue);
} else {
await this.redisClient.set(key, stringValue);
}
}
async get(key: string): Promise<any> {
const value = await this.redisClient.get(key);
return value ? JSON.parse(value) : null;
}
async del(key: string): Promise<void> {
await this.redisClient.del(key);
}
}
- 创建 Redis 模块
src/redis/redis.module.ts
:
typescript
import { Module } from '@nestjs/common';
import { RedisService } from './redis.service';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [ConfigModule],
providers: [RedisService],
exports: [RedisService],
})
export class RedisModule {}
使用 Redis 服务
在需要使用 Redis 的模块中:
typescript
import { Module } from '@nestjs/common';
import { RedisModule } from '../redis/redis.module';
import { RedisService } from '../redis/redis.service';
@Module({
imports: [RedisModule],
providers: [YourService],
})
export class YourModule {
constructor(private readonly redisService: RedisService) {}
async someMethod() {
// 存储数据
await this.redisService.set('key', { data: 'value' }, 3600); // 1小时过期
// 获取数据
const data = await this.redisService.get('key');
// 删除数据
await this.redisService.del('key');
}
}
Docker 部署
使用 Docker Compose 配置开发环境:
yaml
version: '3'
services:
mysql:
image: mysql:8.0
container_name: blog-mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
MYSQL_DATABASE: ${DB_DATABASE}
MYSQL_USER: ${DB_USERNAME}
MYSQL_PASSWORD: ${DB_PASSWORD}
ports:
- "3306:3306"
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:7.0
container_name: blog-redis
restart: always
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
mysql_data:
redis_data:
最佳实践
-
数据库连接管理
- 使用连接池管理数据库连接
- 实现重试机制处理连接失败
- 在生产环境中禁用
synchronize
选项
-
Redis 使用建议
- 合理设置键的过期时间
- 使用适当的数据结构(String、Hash、List、Set、Sorted Set)
- 实现错误处理和重试机制
- 监控 Redis 内存使用情况
-
安全性考虑
- 使用环境变量管理敏感信息
- 限制数据库用户权限
- 配置 Redis 密码
- 使用 SSL/TLS 加密连接
-
性能优化
- 使用数据库索引
- 实现适当的缓存策略
- 监控查询性能
- 定期清理过期数据
通过以上配置和实践,你可以在 NestJS 项目中高效地使用 MySQL 和 Redis,构建高性能、可扩展的应用程序。
- 本文链接:undefined/article/4
- 版权声明: 本站所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明文章出处!