大家好,我是tomato,最近闲来无事,准备看一看Nest.js相关内容,看了一遍文档,实际留在脑子里的倒没有多少。
最好的提升方式莫不过从demo开始,因此这篇攻略,送给那些想用Nest写后端的宝子们。
本攻略整体思路从数据库开始,一直到后台管理系统的增删改查。
对于我个人也算是一种记录,那么闲话少叙,请尽情享用吧!
参考:传送门一
对于数据库的选择,这里选择MySql,安装的方法网上有很多,这里放一篇博文,直接看这个就好,一步步走没问题: MySql安装一步到位 (如果没装上,评论区留言,我帮你去看)
除了MySql,对于前端不熟悉数据库的宝子,同样需要一款图形化数据库管理工具,我这里选择Navicat,你可以直接使用。
至于Navicat的作用,形象一点来讲,就好比在使用git的时候,你不想来回输入指令,无界面操作可能会遇到很多坑,因此部分人选择使用小乌龟这种工具,有界面、功能提示也很明显,Navicat的作用就在此,大大简化MySql操作过程。
Navicat安装包放在下面,步骤很简单,一路无脑下一步即可,需要注意的是放置路径,理论上放哪儿都行,干就完了。
Navicat安装之后,是有使用期限的,所以需要破解版,你可以直接看这个:(同样是实操可行,一步步走,有问题的话,直接把报错信息复制,去搜索查找,解决方案很完善)
目前咱们数据库有了,操作数据库的图形化界面也有了,接下来就需要安装并使用Nest.js了。
老规矩,先在cmd命令窗口(Win+R),终端运行指令:
npm i -g @nestjs/cli // 全局安装Nest(这个指令的作用就是给你,全局安装 NestJS CLI)
再运行第二个指令:
nest new project-name(搞完这一步,脚手架就搭建好了)
在CMD界面,它会问你用什么安装包,我这里用的是pnpm,所以接下来再安装任何插件,你直接用pnpm就行。
接下来,你就可以在vscde,直接开始写后端服务了。
这个是文件目录,你在刚创建完之后,会比我少几个,问题不大,后面都会有的。
项目目录,多数和vue项目类似,比如node_modules等,保证干货,就不多赘述啦。
大家需要注意四个文件,main.ts是入口文件,和前端一样。app.service.ts文件,用来写接口的实际逻辑。在这里你会定义各种方法,各种增删改查操作,都在这里写。
app.controller.ts文件,它的作用主要是用来调用app.service.ts,也就是说方法都写在后者,然后前者负责调用,关系是这样的。
app.module.ts主要是做相关配置的文件,后面详谈,一通大白话讲完,相信你已经很清晰了。
项目启动方式如下(没有任何error类报错,就是成功了)
npm/pnpm start
这里我教你在哪看项目首页:
一般项目刚启动,都是http://localhost:9080 这个地址,你在浏览器直接打开就行。
然后你就会看到经典的hello world!页面,这里注意我的网址,是可以随意更改的,后面讲。
hello world也可以修改,对应的代码在这里。
如何修改页面的地址?
首先在本地起项目,“http://localhost:”是固定的 ,再往后对于端口的定义,要去主文件更改(不是唯一的方式)
代码都一样,你可以跟着走,端口我定义为了1910,前面的process.env.PORT是环境变量,前端里也有,通用的,此时没有,所以端口为1910。
可我后面是什么呢?怎么写路由?
还是回到主文件,定义你的固定路由,类似前端的baseUrl(你找到对应位置,写一下,自行感受,这里我写的是api)
但是问题来了,不同的数据库,不同的表,从路径上是不是要区分?比如这个接口,表叫post,那么对应的路由也得变,在下面这里改。
上面提到,app.controller.ts是调用接口逻辑的文件,那么不同接口,是不是也得变一个路由?(看图)
就是这个叫hello的路由,说完这些,就拼起来了。下图你也就明白是什么意思了,本地+端口+baseUrl+表名+接口路径
我知道你现在很想写接口,但你别急,还差两步,后面你会更丝滑(对于nest的初学,先把实际的搞明白,先写起来,剩下所谓的理论部分,慢慢啃就行,听完上面的内容,对于其它你目前“非重要”的疑问,暂时保留,因为不重要)
最开始讲到,咱们mysql有了,操作mysql的图形化工具navicat有了,那么数据库这边怎么用呢?
一般情况下,打开电脑,你得先把mysql启动起来,只有启动才能连接。
指令如下:
net start mysql
需要提一句的是,最开始,你在安装mysql的过程中,一定设置了环境变量,环境变量的作用就是“全局化”,直白一点,我不用非得进入到mysql的文件夹,再打开cmd,相反,我随便打开cmd,输入上述命令,就能启动。
所以这一步有的人会启动不了,其实就是全局化的问题,不妨做个实验,你去mysql安装路径,打开cmd试一试,一定是好使的,所以如果报错了,复制一下错误,去网上搜索,一个指令就可以解决。(不多提)
如下为启动成功案例:
启动之后,你再用navicat把数据库连上:
随后你会进入到这个界面:
固定的不动,连接名随便起,这个不是服务器名字,是你的连接名字。密码是你的mysql安装时设置的密码。
连接成功之后,你会看到我叫blog的数据库亮了,变绿了,那就是成功了。上图左下角有个测试连接,能测试出你是否成功连上数据库。
这里面有几个小坑,有的人连不上,细心一点,把报错cv一下,搜一搜就出来了。
上图中,post,user,profile都是我的表。
好,那么mysql和navicat这两块拿下,接下来咱们回到vscode代码中。
你需要安装最后一个插件,那就是prisma,它是一个开源的ORM框架,复杂的理论不说了,没必要,也挺晦涩的。
其实它的作用就是帮你定义数据库的数据,然后把数据往数据库里面插入,你用这个,就可以在vscode里面,写js代码,操作数据库,就这么直白。
同样,prisma功能很强大,需要日后你去慢慢探索,下面是它的官方文档,以后慢慢看。
安装prisima有两个指令,第一步先安装,第二步就是初始化,这个初始化其实和git初始化类似,可以帮助你快速理解。
pnpm install prisma // 安装
npx prisma init // 初始化
初始化成功后,你的项目会多两个文件,如图:
其中这个schema.prisma文件,作用就是往里写逻辑,写数据,然后放在数据库里,够直白了吧,如图。
它上面的migrations记录了一些操作记录,暂时不用管,日后你慢慢探索。
下面这个env,其实就是前端的环境变量,如图:
了解这些之后,你要做的是,把prisma和nest连接上,这样才能使用,这一块其实在文档里写的很明白了。
你要做的是,去env文件,把url定义好,如图:
最前面的mysql固定,咱们用的就是,://root固定,在本地,后面的a1326104255是数据库密码,再往后的3306就是端口号,上面我已经教你怎么设置了,再往后直接照抄。(细节去看一下文档就行)
"mysql://root:a1326104255@localhost:3306/blog?schema=public"
做完这些,终于可以写接口了,首先先往你的schema.prisma文件里,写点数据,我给你一个例子,先cv再感悟:
这个没有的先加上,和上述连接是对应的,能映射上,我一起给你放上,直接cv。
// This is your Prisma schema file,
// learn more about it in the docs: https://pris.ly/d/prisma-schema
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model Post {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
title String @db.VarChar(255)
content String?
published Boolean @default(false)
author User @relation(fields: [authorId], references: [id])
authorId Int
}
model Profile {
id Int @id @default(autoincrement())
bio String?
user User @relation(fields: [userId], references: [id])
userId Int @unique
}
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
profile Profile?
}
举个例子,model是固定写法,在prisma里面都有,后面比如Profile是mysql的表名,大括号对象里的是“插入的内容”。
另外你会发现,页面代码都是白色的,看着冷冰冰的,连代码提示都没有,因此,你需要下载一个插件。(下载之后就好啦)
接着你需要把写的内容,插入数据库中,给你两个命令:
npx prisma migrate dev
npx prisma migrate dev --name test
第一个是根据schema.prisma文件,生成并执行sql,往里插数据
第二个同理,区别在于可以指定名字。
选一个就行。
咱们去navicat里面看,图一是咱们插入的表,图二为对应的数据,我这里数据:
数据库也有数据了,接下来终于到了CURD环节,开始写接口!
写接口之前,prisma需要一步操作,那就是注入客户端。这里涉及到三个文件,module、controller和service。
在module里面,你得注册prisema,代码如下:(先不要着急cv,我告诉你在哪)
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { PostsModule } from './posts/posts.module';
import { PrismaClient } from '@prisma/client';
// import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [PostsModule],
controllers: [AppController],
providers: [AppService, PrismaClient],
})
export class AppModule { }
import引入,再进行注册。
然后是service,你同样需要引入prisma,这里我写了点接口,你可以先直接用,然后后面告诉你为什么这么写。(对照一下,和你的有什么区别,别弄错了)
import { Injectable } from '@nestjs/common';
import { PrismaClient } from '@prisma/client';
@Injectable()
export class AppService {
constructor(private readonly appService: PrismaClient) { }
getHello(): string {
return 'Hello World!';
}
async findAllPosts() {
return this.appService.post.findMany();
}
async findPostsById(id: number) {
return this.appService.post.findUnique({
where: { id },
});
}
async createPosts(data: any) {
return this.appService.post.create({
data,
});
}
async updatePosts(id: number, data: any) {
return this.appService.post.update({
where: { id },
data,
});
}
async deletePosts(id: number) {
return this.appService.post.delete({
where: { id },
});
}
}
接口逻辑写完,那么我们需要在控制器上引入,也就是controller文件。
import { Controller, Get, Post, Body, Param, Put, Delete } from '@nestjs/common';
import { AppService } from './app.service';
import { Post as MyPost } from '@prisma/client';
@Controller('posts')
export class AppController {
constructor(private readonly appService: AppService) { }
@Get()
async findAll(): Promise<MyPost[]> {
return this.appService.findAllPosts();
}
@Get('hello')
getHello(): string {
return this.appService.getHello();
}
@Get(':id')
async findOne(@Param('id') id: string): Promise<MyPost | null> {
return this.appService.findPostsById(+id);
}
@Post()
async create(@Body() postData: { title: string; content?: string; published?: boolean; authorId: number }): Promise<MyPost> {
return this.appService.createPosts(postData);
}
@Put(':id')
async update(@Param('id') id: string, @Body() updateData: { title?: string; content?: string; published?: boolean }): Promise<MyPost | null> {
return this.appService.updatePosts(+id, updateData);
}
@Delete(':id')
async remove(@Param('id') id: string): Promise<MyPost | null> {
return this.appService.deletePosts(+id);
}
}
随后咱们可以找一个接口,比如下面这个:
用apiFox试一下:
再打开navicat去看一下表数据:
已经成功添加,其余删改查,你同样可以去看里面的代码,小demo实例都在里面。
目前算是基本完成,后续完善待更新,fighting!