创建项目
// 全局安装 Nest
npm i -g @nestjs/cli
// 创建 nest-demo 项目
nest new nest-demo
// 习惯用那个就选那个
? Which package manager would you ❤️ to use? (Use arrow keys)
> npm
yarn
pnpm
项目比较关键的文件
src 目录下
-- app.controller.spec.ts // 基本控制器的单元测试样例
-- app.controller.ts // 控制器文件,可以简单理解为路由文件
-- app.module.ts // 模块文件,在 NestJS 里主要操作的就是模块
-- app.service.ts // 服务文件,业务逻辑编写在这里
-- app.main.ts // 项目的入口文件,里边包括项目的主模块和监听端口号
运行项目
// 普通运行
npm run start
// 热更新运行
npm run start:dev
// 访问地址
http://localhost:3000
下载 mysql
官网:dev.mysql.com/
1.进入官网后,移动到最下面选择 MySQL Community Server。
2.选择版本和操作系统,点击 go to download page。
3.点击下载。
4.安装流程网上有很多,就不一一介绍了,建议直接安装在C盘,就不需要配置环境变量了。
5.安装成功后,搜索mysql,选择MySQL 8.0 Command Line Client,然后输入安装中自己定义的密码。
6.成功后,就可以使用 mysql 命令进行操作了,具体用法可自己去官网查看,本文使用 navicat 工具进行操作。
采用 navicat 操作 mysql
1.因为使用的公司的安装包,具体下载就不介绍了,可以网上自行找免费的安装包。
2.打开 navicat 后在文件一栏选择新建连接 - mysql,或直接点连接,然后输入连接名和密码。
3.选择 demo,右键新建数据库,双击数据库,选择表,右键新建表,然后就可以创建字段了。
安装 VSCode 插件 REST Client
每次运行后,都要切换到页面中查看,很麻烦,借用 vscode 插件 REST Client,直接在 vscode 中查看接口状态。
1.基础路由:
// 在 src/app.service.ts
@Injectable()
export class AppService {
...
getName(): string {
return 'SNOW!';
}
}
// 在 src/app.controller.ts
@Controller()
export class AppController {
...
@Get('name')
getName(): string {
return this.appService.getName();
}
}
// 访问
http://localhost:3000/name
2.顶层路径 api:
// 在 src/app.controller.ts
@Controller('api')
export class AppController {
...
@Get('name')
getName(): string {
return this.appService.getName();
}
}
// 访问
http://localhost:3000/api/name
3.vscode 下载插件 REST Client,使用:
- 安装 REST Client 后,在项目根目录创建 test.http 文件
- 两个例子,一个 GET 请求,一个 POST 请求,左侧是接口地址,右侧是返回的接口信息,接口写完后,点击接口上方的 Send Request 运行。
创建数据库
1.删除 src 中多余的文件,只留如下:
2.安装依赖:
pnpm add @nestjs/typeorm typeorm mysql
3.创建仓库:
nest g module products
nest g controller products --no-spec
nest g service products --no-spec
4.创建实体:
# 在 src 下创建:entities/products.entity.ts 文件目录
@Entity()
// Products 表名
export class Products extends BaseEntity {
@PrimaryGeneratedColumn()
id: number;
@Column({ type: 'varchar', name: 'name' }) // Column:字段
name: string;
@Column({ type: 'varchar', name: 'sex' })
sex: string;
}
5.连接 mysql 数据库
// 在 app.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ProductsModule } from './products/products.module';
@Module({
imports: [
TypeOrmModule.forRoot({ // 连接数据库
type: 'mysql', // 数据库类型
host: 'localhost', // 数据库ip地址
port: 3306, // 端口
username: 'root', // 登录名
password: 'xxxxxxxx', // 密码
database: 'user', // 数据库名称
entities: [__dirname + '/**/*.entity{.ts,.js}'], // 扫描本项目中.entity.ts或者.entity.js的文件
synchronize: true, // 定义数据库表结构与实体类字段同步(这里一旦数据库少了字段就会自动加入,根据需要来使用)
}),
ProductsModule // 加载子模块
],
controllers: [],
providers: [],
})
export class AppModule {}
// main.js
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.setGlobalPrefix('api/');
await app.listen(3000);
}
bootstrap();
6.修改仓库:
// products.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Products } from '../entities/products.entity';
@Injectable()
export class ProductsService {
constructor(
@InjectRepository(Products)
private readonly productsRepository: Repository<Products>,
) { }
// 查询数据库产品数据
async getList(): Promise<Products[]> {
return await this.productsRepository.query('select * from products');
}
}
// products.controller.ts
import { Controller, Get, Post, Request, Query, Body, Param } from '@nestjs/common';
import { ProductsService } from './products.service';
import { Products } from '../entities/products.entity';
@Controller('products')
export class ProductsController {
constructor(private productsService: ProductsService){}
// 通过数据库查询产品list
@Get('list')
getList(): Promise<Products[]> {
return this.productsService.getList();
}
}
// products.module.ts
import { Module } from '@nestjs/common';
import { ProductsController } from './products.controller';
import { ProductsService } from './products.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { Products } from '../entities/products.entity';
@Module({
imports:[TypeOrmModule.forFeature([Products])],
controllers: [ProductsController],
providers: [ProductsService]
})
export class ProductsModule {}
7.运行项目后,就会在 mysql 中生成表,然后根据字段先手动创建几个数据。
8.在 test.http 中调用接口,就会获取到数据库的数据了。
增删改查
1.修改 products.controller.ts 文件:
@Controller('products')
export class ProductsController {
constructor(private productsService: ProductsService) {}
// 通过数据库查询产品list
@Get('getList')
getList(): Promise<Products[]> {
return this.productsService.getList();
}
// 通过id查询产品
@Get('getProductById')
getProductById(@Query() query: any): Promise<object> {
let id: number = parseInt(query.id);
return this.productsService.getProductById(id);
}
// 增加产品
@Post('addProduct')
addProduct(@Body() body: any): Promise<object> {
return this.productsService.addProduct(body);
}
// 更新产品
@Post('updateProduct')
updateProduct(@Body() body: any): Promise<object> {
return this.productsService.updateProduct(body);
}
// 删除产品
@Post('delProduct')
delProduct(@Body() body: any): Promise<object> {
return this.productsService.delProduct(body);
}
}
2.修改 products.service.ts 文件:
@Injectable()
export class ProductsService {
constructor(
@InjectRepository(Products)
private readonly productsRepository: Repository<Products>,
) {}
// 查询产品数据
async getList(): Promise<Products[]> {
return await this.productsRepository.query('select * from products');
}
// 通过id查询产品
async getProductById(id: any): Promise<any> {
try {
const res = await this.productsRepository.findOne({ where: { id: id } });
return {
code: 200,
data: res,
message: '查询成功',
};
} catch {
return {
code: 500,
message: '查询失败',
};
}
}
// 新增产品
async addProduct(product: any): Promise<object> {
try {
await this.productsRepository.insert(product);
return {
code: 200,
data: null,
message: '新增成功',
};
} catch {
return {
code: 500,
message: '新增失败',
};
}
}
// 更新产品
async updateProduct(product: any): Promise<object> {
try {
await this.productsRepository.update({ id: product.id }, product);
return {
code: 200,
data: null,
message: '更新成功',
};
} catch {
return {
code: 500,
message: '更新失败',
};
}
}
// 删除产品
async delProduct(params: any): Promise<object> {
try {
await this.productsRepository.delete({ id: params.id });
return {
code: 200,
data: null,
message: '删除成功',
};
} catch {
return {
code: 500,
message: '删除失败',
};
}
}
}
3.在 tset.http 中调用上述接口,就可以进行数据的增删改查了。
最后
这只是最基础的使用,感兴趣的可以自己找一些文档学习,后面有时间会介绍如何生成 api 文档,以及进行服务器的部署。