在Nestjs(一)中前期准备中提到了安装MongoDB,此次就用MongoDB实现CRUD。
Start(回顾Nest的核心)
- 创建Module :
nest g mo user server
- 脚手架工具会自动在
src/server/user
文件夹下创建一个user.module.ts
,这是 Nest 的模块文件,Nest 用它来组织整个应用程序的结构。- 会在根模块
app.module.ts
中:
- 顶部引入
UserModule
模块,相当于一个树形结构,在根模块中引入了User
模块。- 同时也在
@Module
装饰器的 imports 中引入了UserModule
。
- 创建 Controller:
nest g co user server
自动生成user.controller.ts
文件,里面内容如下:
//user.controller.ts
import { Controller } from '@nestjs/common';
@Controller('user')
export class UserController {}
在Nest(一)中已经了解到controller 类似前端的路由,负责处理和,所以是写接口的地方,举例子:
//user.controller.ts
import { Controller,Get } from '@nestjs/common';
@Controller('user')
export class UserController {
@Get()
findAll(): string {
return 'All Users';
}
}
- 创建 Provider:
nest g s user server
// user.service.ts
import { Injectable } from '@nestjs/common';
@Injectable()
export class UserService {}
注意:此时user.module.ts
中的内容发生了变化:
// user.module.ts
import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
@Module({
controllers: [UserController],
providers: [UserService]
})
export class UserModule {}
连接数据库
- 安装依赖
在上次的项目基础上安装:
npm install --save mongoose @nestjs/mongoose
- 根模块引入 Mongoose
// app.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './server/user/user.module';
@Module({
imports: [MongooseModule.forRoot('mongodb://localhost/:aaa/prismaTest'), UserModule],
controllers: [AppController],
providers: [AppService]
})
export class AppModule {}
mongodb://localhost/:aaa/bbb
是连接数据库的地址,aaa
是数据库端口号,prismaTest
是数据库名。
- 引入其他模块
- 先要创建一个数据表的格式,在
src/server/user
文件夹下创建一个user.schema.ts
文件,定义一个数据表的格式:
// user.schema.ts
import { Schema } from 'mongoose';
export const userSchema = new Schema({
name: { type: String, required: true },
password: { type: String, required: true },
age: { type: Number, required: true },
email: { type: String, required: true }
});
- 修改
user.module.ts
// user.module.ts
import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { UserController } from './user.controller';
import { userSchema } from './user.schema';
import { UserService } from './user.service';
@Module({
imports: [MongooseModule.forFeature([{ name: 'Users', schema: userSchema }])],
controllers: [UserController],
providers: [UserService]
})
export class UserModule {}
- 添加构造函数
user.service.ts
文件,为UserService
类添加一个构造函数,让其在实例化的时候能够接收到数据库 Model,这样才能在类中的方法里操作数据库。
// user.service.ts
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { CreateUserDTO, EditUserDTO } from './user.dto';
import { User } from './user.interface';
@Injectable()
export class UserService {
constructor(@InjectModel('Users') private readonly userModel: Model<User>) {}
// 查找所有数据
async findAll(): Promise<User[]> {
return = await this.userModel.find();
}
// 查找单条数据
async findOne(_id: string): Promise<User> {
return await this.userModel.findById(_id);
}
// 添加单条数据
async addOne(body: CreateUserDTO): Promise<User> {
return await this.userModel.create(body);
}
// 编辑单条数据
async editOne(_id: string, body: EditUserDTO): Promise<User> {
return await this.userModel.findByIdAndUpdate( _id, body, { new: true });
}
// 删除单条数据
async deleteOne(_id: string): Promise<User> {
return await this.userModel.deleteOne({ _id: _id });
}
}
因为 mongoose 操作数据库其实是异步的,所以这里我们使用 async 函数来处理异步的过程。
到目前为止会报错,因为缺少文件user.interface.ts
和user.dto.ts
:
- user.interface.ts
// user.interface.ts
import { Document } from 'mongoose';
export interface User extends Document {
readonly name: string;
readonly password: string;
readonly age: number;
readonly email: string;
}
- user.dto.ts (数据传输对象)
// user.dto.ts
export class CreateUserDTO {
readonly name: string;
readonly password: string;
readonly age: number;
readonly email: string;
}
export class EditUserDTO {
readonly name: string;
readonly password: string;
readonly age: number;
readonly email: string;
}
CRUD (设置路由)
//user.controller.ts
import { Controller, Get, Post, Put, Body, Delete, Param } from '@nestjs/common';
import { CreateUserDTO, EditUserDTO } from './user.dto';
import { User } from './user.interface';
import { UserService } from './user.service';
interface UserResponse<T = unknown> {
code: number;
data?: T;
message: string;
}
@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) { }
// GET /user/users
@Get('users')
async findAll(): Promise<UserResponse<User[]>> {
return {
code: 200,
data: await this.userService.findAll(),
message: 'Success.'
};
}
}
因为连接的是我之前使用过的数据库
prismaTest
,所以里面是有数据的。
在查询的路由基础上加入下面增加的路由:
@Post()
async addOne(@Body() body: CreateUserDTO): Promise<UserResponse> {
let result = await this.userService.addOne(body);
return {
code: 200,
data: result,
message: 'Success.'
};
}
@Put(':_id')
async editOne(
@Param('_id') _id: string,
@Body() body: EditUserDTO
): Promise<UserResponse> {
let result = await this.userService.editOne(_id, body);
return {
code: 200,
data: result,
message: 'Success.'
};
}
将上面增加的_id为602253c4b6d3bd2a6b6d6ffa的数据的age改为18:
@Delete(':_id')
async deleteOne(@Param('_id') _id: string): Promise<UserResponse> {
let result = await this.userService.deleteOne(_id);
return {
code: 200,
data: result,
message: 'Success.'
};
}
删除上面增加的_id为602253c4b6d3bd2a6b6d6ffa的数据