Skip to content

先前我们已经创建好了一个基础的NestJS工程,接下来我们来给它加上数据库功能

本例子将使用Mongoose连接数据库

创建数据库服务

我这里使用的是一个免费的线上服务进行临时测试,具体可以根据自己手头上的资源进行选择

创建完毕后将相关配置信息填入环境变量文件

安装依赖

sh
pnpm add mongoose @nestjs/mongoose
pnpm add -D @types/mongoose

数据库配置

修改apps/api/src/app.module.ts,在imports中增加MongooseModule配置项和相关的环境变量

ts
// ...
import { MongooseModule } from '@nestjs/mongoose'
@Module({
  imports: [
    ConfigModule.forRoot({
      validationSchema: Joi.object({
        // ...
        MONGODB_URL: Joi.string().required(),
      }),
    }),
    MongooseModule.forRootAsync({
      inject: [ConfigService],
      useFactory: (config: ConfigService) => {
        return {
          uri: config.get('MONGODB_URL'),
        }
      },
    }),
  ],
  // ...
})

定义模型

新建apps/api/src/schemas/user.schema.ts

ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'
import { Document } from 'mongoose'
export enum UserStatus {
  NORMAL = 0, // 正常
  LOCKED = 1, // 锁定
  BANNED = 2, // 封禁
}
export type UserDocument = User & Document
@Schema({ versionKey: false })
export default class User extends Document {
  @Prop({ required: true, unique: true })
  username: string
  @Prop({ required: true })
  password: string
  @Prop({ required: true })
  salt: string
  @Prop({ default: '' })
  avatar: string
  @Prop({ default: 0 })
  role: number
  @Prop({ default: UserStatus.NORMAL, enum: UserStatus })
  status: UserStatus
}
export const UserSchema = SchemaFactory.createForClass(User)

CURD

这里以Auth模块为例

修改auth.module.ts,导入User模型

ts
import { MongooseModule } from '@nestjs/mongoose'
import User, { UserSchema } from '../schemas/user.schema'
@Module({
  imports: [
    // ...
    MongooseModule.forFeature([{ name: User.name, collection: 'user', schema: UserSchema }]) 
  ],
  // ...
})

修改auth.service.ts,把之前的模拟数据替换为从数据库查出来的

ts
import { InjectModel } from '@nestjs/mongoose'
import { Model } from 'mongoose'
import User, { UserDocument, UserStatus } from '../schemas/user.schema'
export class AuthService {
  constructor(
    // ...
    @InjectModel(User.name) private readonly userModel: Model<UserDocument> 
  ) {}
  async validateUser(data: { username: string; password: string }): Promise<ValidResult> {
    const user = await this.userModel.findOne({ username: data.username }).exec() 
    // ...
    const { password, salt, _id, ...result } = user.toJSON()
    return {
      type: 'NORMAL',
      message: 'ok',
      result: { ...result, id: user.id },
    }
  }
}

MIT License