实战使用 NestJS 搭建一个 Admin 后台服务 - 02. typeorm 操作 mysql&基础 crud

实战使用 NestJS 搭建一个 Admin 后台服务 - 01. 项目搭建、配置文件和路由

实战使用 NestJS 搭建一个 Admin 后台服务 - 02. typeorm 操作 mysql&基础 crud

上一篇已经搭建好基本的框架,本篇将开始使用 typeorm 操作 mysql 数据库,实现 crud 操作,以及入参校验。直接开整。

GitHub 项目地址,欢迎各位大佬 Star。

mysql 数据库自备

一、引入 typeorm

1、依赖安装

bash 复制代码
yarn add @nestjs/typeorm typeorm mysql2

2、配置文件修改

  • 修改 config/config.ts
ts 复制代码
export default () => ({
  port: parseInt(process.env.PORT, 10) || 3003,
  database: {
    host: process.env.DATABASE_HOST,
    port: parseInt(process.env.DATABASE_PORT, 10) || 3306,
    username: process.env.DATABASE_USER,
    password: process.env.DATABASE_PASSWORD,
    database: process.env.DATABASE_DATABASE,
  },
});
  • 修改.env
bash 复制代码
# 端口
PORT=3003
# 数据库配置
DATABASE_HOST=localhost
DATABASE_PORT=3306
DATABASE_USER=root
DATABASE_PASSWORD=q847164495
DATABASE_DATABASE=nest_demo # 数据库名自行设置
  • 修改 app.module.ts 文件
ts 复制代码
import { Module } from '@nestjs/common';
import { UsersModule } from './routers/users/users.module';
import { ConfigModule, ConfigService } from '@nestjs/config';
import config from 'config/config';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [
    /** 环境变量配置 */
    ConfigModule.forRoot({
      isGlobal: true,
      load: [config],
    }),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule], // 记得导入 ConfigModule
      /** 配置的使用 */
      useFactory: async (configService: ConfigService) => ({
        type: 'mysql',
        host: configService.get<string>('database.host'),
        port: configService.get<number>('database.port'),
        username: configService.get<string>('database.username'),
        password: configService.get<string>('database.password'),
        database: configService.get<string>('database.database'),
        synchronize: true,
        autoLoadEntities: true,
        timezone: '+08:00', // 东八时区
      }),
      inject: [ConfigService],
    }),
    UsersModule,
  ],
})
export class AppModule {}

二、开始基础的 crud 操作

1、修改实体类

  • 修改 users/entities/users.entity.ts
  • @Entity() 装饰类 标记为实体
ts 复制代码
import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
  CreateDateColumn,
  UpdateDateColumn,
} from 'typeorm';

@Entity()
export class User {
  /** 每个实体必须至少有一个主列 */
  @PrimaryGeneratedColumn()
  id: number;

  /** @CreateDateColumn 是一个特殊列,自动为实体插入日期。无需设置此列,该值将自动设置。 */
  @CreateDateColumn({
    type: 'timestamp',
    nullable: false,
    name: 'create_time',
    comment: '创建时间',
  })
  createTime: Date;

  /** @UpdateDateColumn 是一个特殊列,在每次调用实体管理器或存储库的save时,自动更新实体日期。无需设置此列,该值将自动设置。 */
  @UpdateDateColumn({
    type: 'timestamp',
    nullable: false,
    name: 'update_time',
    comment: '更新时间',
  })
  updateTime: Date;

  @Column({ unique: true, nullable: true, comment: '用户名' })
  username: string;

  @Column({ unique: true, nullable: true, comment: '邮箱' })
  email: string;

  @Column({ unique: true, nullable: true, comment: '手机号' })
  phone: string;

  @Column({ nullable: true, comment: '头像' })
  avatar: string;

  @Column({ nullable: true, comment: '密码' })
  password: string;
}

2、创建数据库

  • 数据库名和配置一致
  • npm run start 启动项目 orm 会自动进行数据库迁移(可自行关闭)
  • 主要就是依赖 @Entity() 装饰的类

可以看到数据库里已经创建好了表

三、操作数据库进行 crud

1、module 导入

  • 修改 users/dto/create-user.dto.ts
  • users/dto/update-user.dto.ts 看情况修改,一般不需要修改
  • 下篇中参数检验需要用到
ts 复制代码
import { User } from '../entities/user.entity';

export class CreateUserDto extends User {}
ts 复制代码
import { PartialType } from '@nestjs/mapped-types';
import { CreateUserDto } from './create-user.dto';

/** 直接继承了 且 声明为可选参数 */
export class UpdateUserDto extends PartialType(CreateUserDto) {}
  • src/types/global.d.ts 创建该文件,写全局类型
ts 复制代码
declare namespace Global {
  type RuleResType<T> = {
    code: number;
    message: string;
    data: T;
    total?: number;
  };
}
  • 修改 users.module.ts 文件
ts 复制代码
import { Module } from '@nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';

@Module({
  /** 导入数据库实体类 */
  imports: [TypeOrmModule.forFeature([User])],
  controllers: [UsersController],
  providers: [UsersService],
})
export class UsersModule {}
  • 编写 service,修改 users.service.ts 文件
ts 复制代码
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 { DeleteResult, Repository, UpdateResult } from 'typeorm';
import { User } from './entities/user.entity';

@Injectable()
export class UsersService {
  /** s实体注册 */
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
  ) {}

  async create(
    createUserDto: CreateUserDto,
  ): Promise<Global.RuleResType<User>> {
    const { username, password, email, phone, avatar } = createUserDto;
    const data = await this.userRepository.save({
      username,
      password,
      email,
      phone,
      avatar,
    });
    return { code: 200, message: '创建成功', data };
  }

  async findAll(): Promise<Global.RuleResType<User[]>> {
    const data = await this.userRepository.find();
    return { code: 200, message: '查询成功', data };
  }

  async findOne(id: number): Promise<Global.RuleResType<User>> {
    const data = await this.userRepository.findOne({ where: { id: id } });
    return { code: 200, message: '查询成功', data };
  }

  async update(
    id: number,
    updateUserDto: UpdateUserDto,
  ): Promise<Global.RuleResType<UpdateResult>> {
    const data = await this.userRepository.update(id, updateUserDto);
    return { code: 200, message: '更新成功', data };
  }

  async remove(id: number): Promise<Promise<Global.RuleResType<DeleteResult>>> {
    const data = await this.userRepository.delete(id);
    return { code: 200, message: '删除成功', data };
  }
}
  • users.controller 暂不修改

四、接口测试

  • npm run start

  • 创建接口 注意@Column({ unique: true, nullable: true, comment: '用户名' }) 时unique 的唯一性

  • 查询接口
  • 更新
  • 删除

下一篇

本篇已经完成了基本的curd,下篇将介绍参数校验,以及使用 swagger 生成接口文档,同时直接导入apifox使用

相关推荐
weixin_4624462314 分钟前
使用 Go 实现 SSE 流式推送 + 打字机效果(模拟 Coze Chat)
开发语言·后端·golang
JIngJaneIL33 分钟前
基于springboot + vue古城景区管理系统(源码+数据库+文档)
java·开发语言·前端·数据库·vue.js·spring boot·后端
小信啊啊1 小时前
Go语言切片slice
开发语言·后端·golang
Victor3563 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端
缘不易3 小时前
Springboot 整合JustAuth实现gitee授权登录
spring boot·后端·gitee
Kiri霧3 小时前
Range循环和切片
前端·后端·学习·golang
WizLC3 小时前
【Java】各种IO流知识详解
java·开发语言·后端·spring·intellij idea
Victor3563 小时前
Netty(19)Netty的性能优化手段有哪些?
后端
爬山算法3 小时前
Netty(15)Netty的线程模型是什么?它有哪些线程池类型?
java·后端
白宇横流学长4 小时前
基于SpringBoot实现的冬奥会科普平台设计与实现【源码+文档】
java·spring boot·后端