警告 在本文中,您将学习如何使用自定义组件从头开始基于 Mongoose 包创建
DatabaseModule
。因此,此解决方案包含大量开销,您可以使用现成的、开箱即用的专用@nestjs/mongoose
包来省略这些开销。要了解更多信息,请参阅 此处。
Mongoose 是最流行的 MongoDB 对象建模工具。
入门
要开始使用此库,我们必须安装所有必需的依赖项:
$ npm install --save mongoose
我们需要做的第一步是使用 connect()
函数与我们的数据库建立连接。 connect()
函数返回一个 Promise
,因此我们必须创建一个 异步提供程序。
import * as mongoose from 'mongoose'
export const databaseProviders = [
{
provide: 'DATABASE_CONNECTION',
useFactory: (): Promise<typeof mongoose> =>
mongoose.connect('mongodb://localhost/nest'),
},
]
按照最佳实践,我们在带有 *.providers.ts
后缀的分离文件中声明了自定义提供程序。
然后,我们需要导出这些提供程序,使它们可供应用程序的其余部分访问。
import { Module } from '@nestjs/common'
import { databaseProviders } from './database.providers'
@Module({
providers: [...databaseProviders],
exports: [...databaseProviders],
})
export class DatabaseModule {}
现在我们可以使用 @Inject()
装饰器注入 Connection
对象。每个依赖于 Connection
异步提供程序的类都将等待,直到 Promise
被解析。
模型注入
使用 Mongoose,所有内容都来自 Schema。让我们定义 CatSchema
:
import * as mongoose from 'mongoose'
export const CatSchema = new mongoose.Schema({
name: String,
age: Number,
breed: String,
})
CatsSchema
属于 cats
目录。此目录代表 CatsModule
。
现在是时候创建一个 Model 提供程序了:
import { Connection } from 'mongoose'
import { CatSchema } from './schemas/cat.schema'
export const catsProviders = [
{
provide: 'CAT_MODEL',
useFactory: (connection: Connection) => connection.model('Cat', CatSchema),
inject: ['DATABASE_CONNECTION'],
},
]
在实际应用中,您应该避免使用魔法字符串。CAT_MODEL
和 DATABASE_CONNECTION
都应保存在单独的 constants.ts
文件中。
现在我们可以使用 @Inject()
装饰器将 CAT_MODEL
注入到 CatsService
:
import { Model } from 'mongoose'
import { Inject, Injectable } from '@nestjs/common'
import { Cat } from './interfaces/cat.interface'
import { CreateCatDto } from './dto/create-cat.dto'
@Injectable()
export class CatsService {
constructor(
@Inject('CAT_MODEL')
private catModel: Model<Cat>,
) {}
async create(createCatDto: CreateCatDto): Promise<Cat> {
const createdCat = new this.catModel(createCatDto)
return createdCat.save()
}
async findAll(): Promise<Cat[]> {
return this.catModel.find().exec()
}
}
在上面的例子中,我们使用了 Cat
接口。此接口扩展了 mongoose 包中的 Document
:
import { Document } from 'mongoose'
export interface Cat extends Document {
readonly name: string
readonly age: number
readonly breed: string
}
数据库连接是异步的,但 Nest 使这个过程对最终用户完全不可见。CatModel
类正在等待数据库连接,而 CatsService
则被延迟,直到模型准备好使用。当每个类被实例化时,整个应用程序就可以启动。
这是最终的 CatsModule
:
import { Module } from '@nestjs/common'
import { DatabaseModule } from '../database/database.module'
import { CatsController } from './cats.controller'
import { CatsService } from './cats.service'
import { catsProviders } from './cats.providers'
@Module({
imports: [DatabaseModule],
controllers: [CatsController],
providers: [
CatsService,
...catsProviders,
],
})
export class CatsModule {}
不要忘记将 CatsModule
导入到根 AppModule
。
示例
此处 中提供了一个工作示例。