NestJS之17- 连接数据库增删改查

1,236 阅读4分钟

前置知识

什么是TypeORM:

TypeORM 是一个基于 TypeScript 的 ORM(对象关系映射)工具,它支持在 Node.js 和浏览器端使用,并且可以与各种关系型数据库进行交互。TypeORM 使用了数据映射器(Data Mapper)模式,可以将实体类中定义的对象映射到数据库中的表,同时支持定义关联关系、查询构建器等功能。

TypeORM 兼容多种数据库,包括 MySQL、PostgreSQL、MariaDB、SQLite、MS SQL Server 等。它提供了类似于 ActiveRecord 的许多功能,比如自动生成 SQL 语句、使用自定义验证器、通过实体或原始 SQL 查询等。

使用 TypeORM 可以简化数据库交互的开发,它提供了清晰的对象映射和高效的查询构建器,使得应用可以更容易地进行 CRUD 操作。在 NestJS 中,TypeORM 被广泛地使用,可以与 NestJS 中提供的同构依赖注入、中间件、拦截器等特性协同工作,构建出功能强大的应用。

image.png

1. 安装mysql

以下是在本地使用Docker安装MySQL的步骤:

  1. 安装Docker

在你的机器上安装Docker的最新版本。这可以通过访问 Docker 官方网站并按照指示下载和安装 Docker。

  1. 下载MySQL Docker镜像

使用命令行或终端来拉取MySQL Docker镜像:

docker pull mysql

3. 启动MySQL容器

在Docker中运行MySQL容器需要使用端口映射来让外部客户端连接到MySQL服务。使用下面的命令将主机端口3306映射到Docker MySQL容器的端口:

复制代码
docker run --name mysqldb -e MYSQL_ROOT_PASSWORD=passwd -p 3306:3306 -d mysql:latest

这将创建一个名为 “mysqldb” 的MySQL容器,并将其启动。 -e 参数将设置 root 用户的密码。

这段命令是使用 Docker 启动一个 MySQL 容器,并对容器进行一些配置。

具体来说:

  • docker run 是启动一个容器的命令;
  • --name mysqldb 是指定容器的名称为 mysqldb
  • -e MYSQL_ROOT_PASSWORD=passwd 是设置 MySQL 的 root 用户的密码为 passwd
  • -p 3306:3306 是将容器的 3306 端口映射到主机的 3306 端口,这样就可以从主机上连接到 MySQL 容器了;
  • -d 是指定容器以后台运行;
  • mysql:latest 是使用最新的 MySQL 镜像。

这样,当你运行了这个命令以后,Docker 就会启动一个名为 mysqldb 的容器,并使用最新版的 MySQL 镜像启动 MySQL 服务。使用 -p 参数将容器的 3306 端口映射到主机的 3306 端口,因此你可以从主机上连接到 MySQL 数据库。使用 -e 参数来设置 MySQL 的 root 用户密码为 passwd。当你运行这个命令时,Docker 会自动从 Docker Hub(一个 Docker 镜像托管网站)下载最新的 MySQL 镜像。

  1. 连接MySQL

现在可以使用MySQL客户端连接到MySQL服务:

mysql -u root -p -h 127.0.0.1 -P 3306

输入自己ip4的地址,进行连接, 输入密码,即可成功连接到MySQL服务。

2. 连接数据库

npm install --save @nestjs/typeorm typeorm mysql2

app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { TestModule } from './test/test.module';

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql', //数据库类型
      username: 'root', //账号
      password: 'passwd', //密码
      host: 'localhost', //host
      port: 3306, //
      database: 'db', //库名
      entities: [__dirname + '/**/*.entity{.ts,.js}'], //实体文件
      synchronize: true, //synchronize字段代表是否自动将实体类同步到数据库
      retryDelay: 500, //重试连接数据库间隔
      retryAttempts: 10, //重试连接数据库的次数
      autoLoadEntities: true, //如果为true,将自动加载实体 forFeature()方法注册的每个实体都将自动添加到配置对象的实体数组中
    }),
    TestModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

nest g res test

实体中定义表的类型 entities/test.entity.ts

import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class Test {
  @PrimaryGeneratedColumn()
  id: number;
  @Column()
  name: string;

  @Column()
  age: number;

  @Column()
  password: number;
}

test.module.ts

import { Module } from '@nestjs/common';
import { TestService } from './test.service';
import { TestController } from './test.controller';
import { Test } from './entities/test.entity';
import { TypeOrmModule } from '@nestjs/typeorm';

@Module({
  imports: [TypeOrmModule.forFeature([Test])],
  controllers: [TestController],
  providers: [TestService],
})
export class TestModule {}

启动后自动实现实体定义的字段

image.png

3. 增删改查操作

3.1 增

app.service.ts

import { Injectable } from '@nestjs/common';
import { CreateTestDto } from './dto/create-test.dto';
import { UpdateTestDto } from './dto/update-test.dto';
import { Repository } from 'typeorm';
import { Test } from './entities/test.entity';
import { InjectRepository } from '@nestjs/typeorm';
@Injectable()
export class TestService {
  constructor(
    @InjectRepository(Test) private readonly testRepository: Repository<Test>,
  ) {}

  async create(createTestDto: CreateTestDto) {
     // 前端传入数据createTestDto
    const newUser = await this.testRepository.create(createTestDto);
    return await this.testRepository.save(newUser);
  }
}

调用:

image.png

3.2 删

async remove(id: number) {
    const userToRemove = await this.testRepository.findOneOrFail({
      where: { id },
    });
    if (!userToRemove) {
      throw new Error(`User with id ${id} not found.`);
    }
    return await this.testRepository.remove(userToRemove);
  }

image.png

id为1的删除了 image.png

3.3 改

async update(id: number, updateTestDto: UpdateTestDto) {
    const updateUser = await this.testRepository.findOne({ where: { id } });
    if (!updateUser) {
      throw new Error(`User with id ${id} not found.`);
    }
    await this.testRepository.merge(updateUser, updateTestDto);
    return await this.testRepository.save(updateUser);
  }

image.png

image.png

4. 查

async findAll() {
    return await this.testRepository.find();
  }

  async findOne(id: number) {
    return await this.testRepository.findOne({ where: { id } });
  }

查所有 image.png

查单个

image.png