node中怎么使用Nest.js 連接 MongoDB 數(shù)據(jù)庫?下面本篇文章給大家介紹一下node 框架 Nest.js 使用 MongoDB 的方法,希望對大家有所幫助!
在學習 Nest 與數(shù)據(jù)庫進行連接時,難免會遇到選擇數(shù)據(jù)庫的問題,這里作者選擇的是 MongoDB
記錄一下簡單使用。 大家可以根據(jù)不同需求選擇合適的數(shù)據(jù)庫。
貼出跟進看的文檔以方便大家進一步學習 Nest 中文文檔 ,MongoDB菜鳥教程
數(shù)據(jù)庫簡介
-
MongoDB 是一個基于分布式文件存儲的數(shù)據(jù)庫。由 C++ 語言編寫。旨在為 WEB 應用提供可擴展的高性能數(shù)據(jù)存儲解決方案。
-
MongoDB 是一個介于關系數(shù)據(jù)庫和非關系數(shù)據(jù)庫之間的產(chǎn)品,是非關系數(shù)據(jù)庫當中功能最豐富,最像關系數(shù)據(jù)庫的。
數(shù)據(jù)庫選擇
- 目前市面上有很多成熟的數(shù)據(jù)庫可供大家選擇。
- 據(jù)翻看各種資料作者這里得出的結(jié)論為大項目用
PostgreSql
小項目用MongoDB
所以作者準備一起學習下,這次因為想做一個小項目練練手所以先用MongoDB
看看怎么樣。 - 大家有不同看法歡迎在評論區(qū)討論。
配置基本服務
-
確保電腦已經(jīng)安裝了
MongoDB
沒 -
記得弄完做一下環(huán)境配置,可以開機自啟, 也可以選擇自己啟動哈hhh看個人
Mongoose
-
簡單介紹一下 ,
Mongoose
是一個操作MongoDB
的Nodejs
驅(qū)動庫 -
MongoDB
是數(shù)據(jù)庫,Nodejs
是js的一個運行環(huán)境,Nodejs
不直接操作Mongodb
,這個時候就需要相應的驅(qū)動程序來提供接口。 -
在 Nest 項目中安裝一下依賴項,兩種安裝方式,自行選擇
$ npm install --save @nestjs/mongoose mongoose // NPM 安裝 $ yarn add @nestjs/mongoose mongoose // YARN 安裝復制代碼
-
安裝完成后我們在 AppModule 文件中引入一下
/* app.module.ts */ import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; // 我自己準備的 USER 模塊 import { UserModule } from './user/user.module'; // 引入 Mongoose import { MongooseModule } from '@nestjs/mongoose'; @Module({ // 用 forRoot 方法連接數(shù)據(jù)庫 imports: [UserModule, MongooseModule.forRoot('mongodb://localhost/test')], controllers: [AppController], providers: [AppService], }) export class AppModule {}
基礎功能模塊
-
這里用一個 User 模塊來做 demo
-
這里我理解的基礎功能模塊包括
module
(模塊)Controller
(控制器)Service
(提供者)Schema
(數(shù)據(jù)模型) 我們主要是用Nest對
MongoDB
做增刪改查 這幾個模塊目前暫時夠用。 -
對這幾個模塊做一些簡單介紹:
-
由于我們上面已經(jīng)對 app.module.ts 該根模塊已經(jīng)引入過了
mongoose
所以下面我們之間看一下功能模塊是怎樣的
Schema
-
在
Mongoose
中,一切都源于 Scheme,每個Schema
都會映射到MongoDB
的一個集合,并定義集合內(nèi)文檔的結(jié)構(gòu)。Schema
被用來定義模型,而模型負責從底層創(chuàng)建和讀取MongoDB
的文檔。 -
Schema
可以用NestJS
內(nèi)置的裝飾器來創(chuàng)建,或者也可以自己動手使用Mongoose
的常規(guī)方式。使用裝飾器來創(chuàng)建Schema
會極大大減少引用并且提高代碼的可讀性。這里作者用的是官方推薦方式用裝飾器來創(chuàng)建,畢竟用的是 Nest 不得用點特色的hhh。 -
/* user.schema.ts */ import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose'; // @Prop 裝飾器接受一個可選的參數(shù),通過這個,你可以指示這個屬性是否是必須的,是否需要默認值,或者是標記它作為一個常量,下面是例子 // SchemaFactory 是 mongoose 內(nèi)置的一個方法做用是讀取模式文檔 并創(chuàng)建 Schema 對象 import { Document } from 'mongoose'; export type UserDocument = User & Document; @Schema() export class User extends Document { @Prop() name: string; // 設置值為必填 @Prop({ required: true }) age: number; @Prop() height: number; } export const UserSchema = SchemaFactory.createForClass(User);
-
等下和其他功能一起在 Module 中引入。
Service
-
控制器的目的是接收應用的特定請求。路由機制控制哪個控制器接收哪些請求。通常,每個控制器有多個路由,不同的路由可以執(zhí)行不同的操作。
/* user.service.ts */ import { Model } from 'mongoose'; import { InjectModel } from '@nestjs/mongoose'; import { User, UserDocument } from 'src/schema/user.schema'; import { CreateUserDto } from './user.dto'; @Injectable() export class UserService { // 注冊Schema后,可以使用 @InjectModel() 裝飾器將 User 模型注入到 UserService 中: constructor(@InjectModel('User') private userTest: Model<UserDocument>) {} // 添加 async create(createUserDto: CreateUserDto): Promise<User> { const createUser = new this.userTest(createUserDto); const temp = await createUser.save(); return temp; } // 查找 async findAll(): Promise<User[]> { // 這里是異步的 const temp = await this.userTest.find().exec(); return temp; } // 查找 async findOne(name: string): Promise<User[]> { // 這里是異步的 const temp = await this.userTest.find({ name }); return temp; } // 刪除 async delete(sid: number) { // 這里是異步的 remove 方法刪除成功并返回相應的個數(shù) const temp = await this.userTest.remove({ _id: sid }); return temp; } // 修改 async updateUser(sid: string, data: any) { // 這里是異步的 remove 方法刪除成功并返回相應的個數(shù) const temp = await this.userTest.updateOne({ _id: sid }, { $set: data }); return temp; } }
-
等下和其他功能一起在 Module 中引入。
Controller
-
控制器的目的是接收應用的特定請求。路由機制控制哪個控制器接收哪些請求。通常,每個控制器有多個路由,不同的路由可以執(zhí)行不同的操作。
/* user.controller.ts */ // 引入 Nest.js 內(nèi)置的各個功能 import { Body, Controller, Delete, Get, Param, Post, Put, Query } from '@nestjs/common'; // 引入用戶服務 import { UserService } from './user.service'; // 引入創(chuàng)建用戶 DTO 用于限制從接口處傳來的參數(shù) import { CreateUserDto } from './user.dto'; // 配置局部路由 @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} // 創(chuàng)建user路由 user/createUser @Post('createUser') async createUser(@Body() body: CreateUserDto) { return this.userService.create(body); } //查找所有 user 路由 @Get('findAll') async findAll() { return this.userService.findAll(); } // 查找某一個用戶路由 @Get('findOne') async findOne(@Query() query: any) { return this.userService.findOne(query.name); } // 刪除一個用戶的路由 @Delete(':sid') deleteUser(@Param() param: any) { return this.userService.delete(param.sid); } // 更改用戶信息的路由 @Put(':sid') updateUser(@Body() body: any, @Param() param: any) { return this.userService.updateUser(param.sid, body); } }
Moudle
-
模塊是具有
@Module()
裝飾器的類。@Module()
裝飾器提供了元數(shù)據(jù),Nest 用它來組織應用程序結(jié)構(gòu)。 -
我們把以上內(nèi)容引入到我們的 User 模塊中
/* user.module.ts */ import { Module } from '@nestjs/common'; import { UserController } from './user.controller'; import { UserService } from './user.service'; import { MongooseModule } from '@nestjs/mongoose'; import { UserSchema } from 'src/schema/user.schema'; @Module({ // MongooseModule提供了forFeature()方法來配置模塊,包括定義哪些模型應該注冊在當前范圍中。 // 如果你還想在另外的模塊中使用這個模型,將MongooseModule添加到CatsModule的exports部分并在其他模塊中導入CatsModule。 // 這里的 name:'User' 為數(shù)據(jù)庫表名稱與 service 中注入的表名稱對應兩者不一樣會報錯 imports: [MongooseModule.forFeature([{ name: 'User', schema: UserSchema }])], controllers: [UserController], providers: [UserService], }) export class UserModule {}
- 以上我們的基礎布局完成,可以進行接口檢驗了
接口檢驗
- 處理這些配置我們還在 main.ts 文件中配置了全局路由
app.setGlobalPrefix('api');
意思就是所有請求前面會有一個/api/
- 這里我們用的
PostMan
和MongoDB Compass
官方推薦的可視化工具查看效果
POST 增
-
這里我使用
POST
請求,路由為/api/user/createUser
因為要限制請求參數(shù)的數(shù)據(jù)類型所以這里方式為application/json
-
因為這里我們之前定義的 User 數(shù)據(jù)模型為 name,age,height, 所以請求里面只需要這幾個參數(shù)即可,別的就算寫進去也添加不到集合中
-
Postman
-
打開 MongoDB Compass 查看數(shù)據(jù)
-
可以看到我們已經(jīng)添加到數(shù)據(jù)庫中一條數(shù)據(jù),接下來我們在添加兩條,方便等會的查詢/刪除/更改操作
GET 查所有
-
這里我使用
GET
請求,,路由為/api/user/findAll
因為這里是查 User 集合內(nèi)所有數(shù)據(jù),所以不用添加請求參數(shù) -
Postman
-
打開 MongoDB Compass 查看數(shù)據(jù)
-
可以看到我們已經(jīng)查詢到數(shù)據(jù)庫中剛才在
User
集合中添加的三條數(shù)據(jù)切記要點REFRESH
建不然軟件不會自己刷新
GET 查單個用戶
-
這里我使用
GET
請求,路由為/api/user/findOne
因為這里是查 User 集合內(nèi)對應搜索條件的數(shù)據(jù)集合,這里我們用的是name 去查詢的。也可以用唯一值 id 去查詢。 -
Postman
-
可以看到返回結(jié)果是一個集合,了解