企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
## Mongoose > 在本文中,您将学习如何使用自定义提供者机制从零开始创建基于 **Mongoose** 包的 `DatabaseModule`。由于该解决方案包含许多开销,因此您可以使用开箱即用的 `@nestjs/mongoose` 软件包。要了解更多信息,请参阅 [此处](https://docs.nestjs.com/techniques/mongodb)。 [Mongoose](http://mongoosejs.com/) 是最受欢迎的[MongoDB](https://www.mongodb.org/) 对象建模工具。 ### 入门 在开始使用这个库前,我们必须安装所有必需的依赖关系 ```bash $ npm install --save mongoose $ npm install --save-dev @types/mongoose ``` 我们需要做的第一步是使用 `connect()` 函数建立与数据库的连接。`connect()` 函数返回一个 `Promise`,因此我们必须创建一个 [异步提供者](/8/fundamentals.md?id=异步提供者 (Asynchronous providers))。 > database.providers.ts ```typescript import * as mongoose from 'mongoose'; export const databaseProviders = [ { provide: 'DATABASE_CONNECTION', useFactory: (): Promise<typeof mongoose> => mongoose.connect('mongodb://localhost/nest'), }, ]; ``` > 按照最佳实践,我们在分离的文件中声明了自定义提供者,该文件带有 `*.providers.ts` 后缀。 然后,我们需要导出这些提供者,以便应用程序的其余部分可以 **访问** 它们。 > database.module.ts ```typescript import { Module } from '@nestjs/common'; import { databaseProviders } from './database.providers'; @Module({ providers: [...databaseProviders], exports: [...databaseProviders], }) export class DatabaseModule {} ``` 现在我们可以使用 `@Inject()` 装饰器注入 `Connection` 对象。依赖于 `Connection` 异步提供者的每个类都将等待 `Promise` 被解析。 ### 模型注入 使用Mongoose,一切都来自[Schema](https://mongoosejs.com/docs/guide.html)。 让我们定义 `CatSchema` : > schemas/cats.schema.ts ```typescript import * as mongoose from 'mongoose'; export const CatSchema = new mongoose.Schema({ name: String, age: Number, breed: String, }); ``` `CatsSchema` 属于 `cats` 目录。此目录代表 `CatsModule` 。 现在,让我们创建一个 **模型** 提供者: > cats.providers.ts ```typescript 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` 中: > cats.service.ts ```typescript import { Model } from 'mongoose'; import { Injectable, Inject } 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` : ```typescript import { Document } from 'mongoose'; export interface Cat extends Document { readonly name: string; readonly age: number; readonly breed: string; } ``` 数据库连接是 **异步的**,但 `Nest` 使最终用户完全看不到这个过程。`CatModel` 正在等待数据库连接时,并且`CatsService` 会被延迟,直到存储库可以使用。整个应用程序可以在每个类实例化时启动。 这是一个最终的 `CatsModule` : > cats.module.ts ```typescript import { Module } from '@nestjs/common'; import { CatsController } from './cats.controller'; import { CatsService } from './cats.service'; import { catsProviders } from './cats.providers'; import { DatabaseModule } from '../database/database.module'; @Module({ imports: [DatabaseModule], controllers: [CatsController], providers: [ CatsService, ...catsProviders, ], }) export class CatsModule {} ``` > 不要忘记将 `CatsModule` 导入到根 `ApplicationModule` 中。