实战使用 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使用

相关推荐
AI人H哥会Java2 小时前
【Spring】控制反转(IoC)与依赖注入(DI)—IoC容器在系统中的位置
java·开发语言·spring boot·后端·spring
凡人的AI工具箱2 小时前
每天40分玩转Django:Django表单集
开发语言·数据库·后端·python·缓存·django
奔跑草-2 小时前
【数据库】SQL应该如何针对数据倾斜问题进行优化
数据库·后端·sql·ubuntu
中國移动丶移不动2 小时前
Java 并发编程:原子类(Atomic Classes)核心技术的深度解析
java·后端
Q_19284999063 小时前
基于Spring Boot的旅游推荐系统
spring boot·后端·旅游
愤怒的代码3 小时前
Spring Boot对访问密钥加密解密——RSA
java·spring boot·后端
美美的海顿3 小时前
springboot基于Java的校园导航微信小程序的设计与实现
java·数据库·spring boot·后端·spring·微信小程序·毕业设计
愤怒的代码3 小时前
Spring Boot中幂等性的应用
java·spring boot·后端
xiaocaibao7774 小时前
编程语言的软件工程
开发语言·后端·golang
0wioiw04 小时前
Flask-----SQLAlchemy教程
后端·python·flask