【NestJS学习笔记】 之 结合TypeORM框架并连接MySQL数据库

218 阅读7分钟

前言,小编最近在学习NestJS系列相关知识,想把自己了解到的知识点作为笔记的同时也分享给大家,本篇涉及的是结合TypeORM框架并连接MySQL数据库的知识,如果有哪里写的不好的话还恳请各位掘友批评指正谢谢,小编将不胜感激,闲话不多说,我们直接步入正题吧...

TypeORM和MySQL在NestJS应用中扮演不同的角色,但它们共同工作以实现数据库操作。我们先简单理解下它们各自的作用和关系:

MySQL:

  1. 角色:MySQL是一个关系型数据库管理系统。

  2. 作用:

    • 存储和管理应用程序的数据
    • 提供数据的持久化
    • 支持复杂的查询和数据操作
    • 确保数据的一致性和完整性

TypeORM:

  1. 角色:TypeORM是一个对象关系映射(ORM)库。

  2. 作用:

    • 在应用程序代码和数据库之间架起桥梁
    • 将JavaScript/TypeScript对象映射到数据库表
    • 提供一种面向对象的方式来操作数据库
    • 简化数据库操作,无需直接编写SQL查询
    • 支持多种数据库系统,包括MySQL

关系:

  1. 抽象层:TypeORM作为一个抽象层,位于我们的NestJS应用和MySQL数据库之间。
  2. 数据映射:TypeORM将我们在NestJS中定义的实体(Entities)映射到MySQL的表。
  3. 查询构建:TypeORM提供了一个查询构建器,允许我们用TypeScript编写类似SQL的查询,然后将其转换为MySQL可以理解的SQL语句。
  4. 数据库连接:TypeORM管理与MySQL数据库的连接,处理连接池等底层细节。
  5. 数据类型转换:TypeORM负责在JavaScript/TypeScript类型和MySQL数据类型之间进行转换。
  6. 迁移支持:TypeORM提供了数据库迁移工具,可以帮助我们管理数据库架构的变更。

项目中引入 typeorm 的项目依赖:

    npm install --save @nestjs/typeorm typeorm mysql2

推荐一个数据库的可视化工具

微信图片_20240719205448.png

开始连接数据库服务

微信图片_20240719205906.png

注意上图中的端口和密码等,是我们安装mysql时设置的,比如图中小编的端口为3307,是在下图时安装配置时小编改的

微信图片_20240719205514.png

连接成功显示如下

微信图片_20240719205909.png

新建一个student数据库

微信图片_20240719210752.png

微信图片_20240719210755.png

微信图片_20240719210927.png

初始化 typeorm 配置

微信图片_20240719211842.png

生成一个 dbTest 的 curd 项目模块

微信图片_20240719212141.png

自动加载实体的实现

微信图片_20240719213817.png

定义 dbTest 中实体文件的内容

微信图片_20240719213820.png

关联实体

微信图片_20240719213823.png

运行项目并查看数据库发现创建成功,student数据库自动加载并创建了我们刚刚自定义的实体

微信图片_20240719213826.png

根据上述实体的实现不难发现:在 NestJS 和 TypeORM 的上下文中,实体(Entity)是一个非常重要的概念。那么实体是什么呢,以及如何在 NestJS 中使用它们,接下来将继续解析

实体(Entity)是什么?

  1. 定义:实体是一个映射到数据库表的类。
  2. 作用:它代表了数据库中的一个表,类的属性对应表的列。
  3. 特点:实体类通常包含基本的属性和方法,用于描述数据结构和行为。

在 NestJS 中如何使用实体:

  1. 创建实体类:
import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn() //自增属性,即对应多行数据时id会自动自增
  id: number;

  @Column() //定义列属性,表明它对应数据库表中的一列
  firstName: string;

  @Column()
  lastName: string;

  @Column({ default: true })
  isActive: boolean;
}
  1. 在模块中导入实体:
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user.entity';

@Module({
  imports: [TypeOrmModule.forFeature([User])],
  // ...
})
export class UsersModule {}
  1. 在服务中使用实体:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './user.entity';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(User)
    private usersRepository: Repository<User>,
  ) {}

  findAll(): Promise<User[]> {
    return this.usersRepository.find();
  }

  findOne(id: number): Promise<User> {
    return this.usersRepository.findOne({ where: { id } });
  }

  async create(user: User): Promise<User> {
    return this.usersRepository.save(user);
  }

  // ... 其他方法
}
  1. 使用装饰器:

    • @Entity(): 标记一个类为实体。
    • @PrimaryGeneratedColumn(): 定义主键并自动生成。
    • @Column(): 定义普通列。
    • @CreateDateColumn(), @UpdateDateColumn(): 自动管理创建和更新时间。
    • @OneToMany(), @ManyToOne(), @ManyToMany(): 定义关系。

上述内容的知识点的关系可以总结为:我们首先使用 Database Client 插件连接了 mysql 服务,提供了可视化工具供我们使用,接着在项目中使用 typeorm 连接了 mysql,在运行项目时将项目中的实体类的相关信息映射到我们连接的 student 数据库,从而对student数据库里面的数据库表进行一些 curd 的操作

补充:小编发现自己有点搞混实体和DTO的区别和作用了,查阅资料后补如下

  1. 目的和使用场景:

    • DTO:主要用于数据传输,定义了客户端和服务器之间如何传输数据。它用于 API 层,处理请求和响应。
    • 实体:代表数据库中的表结构,用于数据持久化。它在数据访问层使用,与数据库交互。
  2. 结构和内容:

    • DTO:通常只包含客户端需要的数据字段,可能是实体的一个子集或组合。
    • 实体:包含数据库表的完整结构,包括所有列和关系。
  3. 装饰器:

    • DTO:主要使用验证装饰器(如 class-validator 中的 @IsNotEmpty(), @IsEmail() 等)。
    • 实体:使用 ORM 相关的装饰器(如 @Entity(), @Column(), @PrimaryGeneratedColumn() 等)。
  4. 业务逻辑:

    • DTO:通常不包含业务逻辑,主要用于数据验证和传输。
    • 实体:可能包含一些与数据相关的业务逻辑和方法。
  5. 生命周期:

    • DTO:在单个请求/响应周期中使用,不持久化。
    • 实体:与数据库记录的生命周期相匹配,可以被持久化。
  6. 灵活性:

    • DTO:更加灵活,可以根据 API 需求自由定义。
    • 实体:结构通常需要与数据库模式保持一致。
  7. 验证和转换:

    • DTO:常用于输入验证和数据转换。
    • 实体:主要关注数据持久化和检索。
  8. 安全性:

    • DTO:可以隐藏敏感信息,只暴露必要的字段给客户端。
    • 实体:包含所有数据库字段,包括可能的敏感信息。
  9. 版本控制:

    • DTO:可以轻松适应 API 版本变化,不影响数据库结构。
    • 实体:变更可能需要数据库迁移。

示例对比:

DTO:

export class CreateUserDto {
  @IsNotEmpty()
  @IsString()
  readonly name: string;

  @IsEmail()
  readonly email: string;

  @IsNotEmpty()
  @MinLength(6)
  readonly password: string;
}

实体:

@Entity()
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  name: string;

  @Column({ unique: true })
  email: string;

  @Column()
  password: string;

  @Column({ default: true })
  isActive: boolean;

  @CreateDateColumn()
  createdAt: Date;

  @UpdateDateColumn()
  updatedAt: Date;
}

总结:
DTO 和实体在 NestJS 应用中扮演不同但互补的角色。DTO 专注于数据传输和 API 交互,而实体则关注数据持久化和数据库交互。使用这两种结构可以帮助你构建更清晰、更安全、更易维护的应用程序架构。

结语:以上就是小编对于 NestJS 中结合 TypeORM 框架并连接 MySQL 数据库的知识点的理解,感谢阅读!!!