安装依赖

1
pnpm add --save @nestjs/typeorm typeorm mysql2

配置数据库连接

app.module.ts中配置数据库连接信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
imports: [ TypeOrmModule.forRoot({
type: 'mysql', // 数据库类型
host: 'localhost', // 数据库主机
port: 3306, // 数据库端口
username: 'root', // 数据库用户名
password: 'root', // 数据库密码
database: 'nest_demo', // 数据库名称
entities: [__dirname + '/**/*.entity{.ts,.js}'], // 数据库实体文件
synchronize: true, // 是否自动同步实体
logging: true, // 是否打印日志
retryDelay: 500, // 重试连接间隔
retryAttempts: 10, // 重试连接次数
autoLoadEntities: true, // 自动加载实体

}), UserModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}

创建实体文件

1
nest g resource user

src/user/entities/user.entity.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

@Entity() // 表名
export class User {
@PrimaryGeneratedColumn() // 主键
id: number;

// @Column({ unique: true, length: 20, nullable: false }) // 列:必填 长度20 默认非空 唯一
@Column()
username: string;

// @Column({ length: 20, nullable: false, select: false }) // 列:必填 长度20 默认非空 不显示
@Column()
password: string;

@Column() // 列
age: number;
}

模块文件

user.module.ts

1
2
3
4
5
6
7
8
9
10
11
12
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';

@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}

增删查改

user.service.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import { User } from './entities/user.entity';
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { hash, verify } from '../utils/md5';

@Injectable()
export class UserService {
// 注释:这里使用@InjectRepository 注解,注入User实体,使用Repository<User>
constructor(
@InjectRepository(User)
private usersRepository: Repository<User>,
) { }
async create(createUserDto: CreateUserDto) {
// 对密码进行加密
createUserDto.password = hash(createUserDto.password, process.env.MD5_SALT)
// 前端传入的数据,保存到数据库中
const user = await this.usersRepository.save(createUserDto) // 保存到数据库中
const { password, ...userWithoutPassword } = user; // 删除密码
return userWithoutPassword
}

async findAll() {
// 查询所有用户
return await this.usersRepository.find();
}

async findOne(id: number) {
// 根据id查询用户
const user = await this.usersRepository.findOneBy({ id })
return user;
}

async update(id: number, updateUserDto: UpdateUserDto) {
const user = await this.usersRepository.update(id, updateUserDto) // 更新
return user;
}

async remove(id: number) {
const user = await this.usersRepository.delete(id)
return user;
}
}

对密码进行加密,使用crypto-js

1
pnpm i crypto-js @types/crypto-js

md5.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import { MD5 } from "crypto-js";

/**
* @description: hash加密
* @param {string} val 要加密的字符串
* @param {*} salt 盐
* @Author: clue
*/
export function hash(val: string, salt = "") {
return MD5(`${val}${salt}`).toString();
}

/**
* @description: 比对加密后的字符串
* @param {string} val 要比对的字符串
* @param {string} hashVal 加密后的字符串
* @param {*} salt 盐
* @Author: clue
*/
export function verify(val: string, hashVal: string, salt = "") {
return hash(val, salt) === hashVal;
}

user.controller.ts

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
import { Controller, Get, Post, Body, Patch, Param, Delete, HttpStatus, HttpException } from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';

@Controller('user')
export class UserController {
constructor(private readonly userService: UserService) { }

@Post()
create(@Body() createUserDto: CreateUserDto) {
return this.userService.create(createUserDto);
}

@Get()
findAll() {
const a = process.env.SALT
return this.userService.findAll();
}

@Get(':id')
findOne(@Param('id') id: string) {
// 根据id查询用户
const user = this.userService.findOne(+id)
if (!user) {
throw new HttpException('用户不存在', HttpStatus.NOT_FOUND)
} else {
return user
}
}

@Patch(':id')
update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
return this.userService.update(+id, updateUserDto);
}

@Delete(':id')
remove(@Param('id') id: string) {
return this.userService.remove(+id);
}
}