暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

使用NestJS和MySQL处理文件上传

原创 eternity 2022-08-18
817

许多开发人员鄙视处理文件上传。这可以归因于缺乏关于最佳方法的知识,或者难以确定如何配置NestJS应用程序来处理文件上传。许多人可能希望将文件直接保存到MySQL数据库,或者保存图像名称并将图像保存在磁盘存储中:这取决于他们的偏好和他们想要实现的目标。本教程将教您如何使用NestJS和MySQL构建文件上传功能。

先决条件

在开始学习本教程之前,请确保您的系统满足以下要求:

设置NestJS

满足上述要求后,继续安装NestJS CLI并通过运行以下命令创建新项目:

Shell
$ npm i -g @nestjs/cli $ nest new file-upload

这些命令将安装NestJS CLI,并使用下面的文件夹结构创建一个新的NestJS项目。
1.png
创建NestJS项目后,进入下一步-通过运行以下命令为应用程序安装所需的依赖项:

Shell
npm install --save @nestjs/typeorm typeorm mysql2 

在上面的命令中,您已经安装了TypeORM和mysql2模块:它们将使您能够将应用程序连接到MySQL数据库并对其执行操作。

设置MySQL数据库

安装了上述依赖项后,继续设置并连接到MySQL数据库。要开始,请在app.module中添加代码,包含以下代码段的ts文件。

TypeScript
...
import { TypeOrmModule } from '@nestjs/typeorm';
import { Image } from './image.entity';

@Module({
  imports: [TypeOrmModule.forRoot({
    type: 'mysql',
    host: 'localhost',
    port: 3306,
    username: 'root',
    password: '1234',
    database: 'blog',
    entities: [Image],
    synchronize: true,
  }),
  TypeOrmModule.forFeature([Image])
  ],
  ...
})
...

在上面的代码段中,我们从前面安装的typeorm模块导入了TypeOrmModule。我们使用forRoot方法将应用程序连接到MySQL数据库,并传入数据库凭据。这里要指出的另一点是entities属性,它允许我们指定模块中的实体,并允许我们访问您不久将创建的映像实体:我们还将synchronize属性设置为true以自动迁移数据库。

创建图像实体

接下来,让我们创建前面提到的图像实体。要开始,请创建image.entity.ts文件,并在下面添加代码段。

TypeScript
import { Entity, Column, PrimaryGeneratedColumn, CreateDateColumn, UpdateDateColumn } from 'typeorm';
​
@Entity()
export class Image {
    @PrimaryGeneratedColumn()
    id: number;
​
    @Column()
    name: string;
​
    @CreateDateColumn()
    dateCreated: Date;
​
    @UpdateDateColumn()
    dateUpdated: Date;

在上面的代码段中,我们导入了创建实体所需的装饰器。使用这些装饰器,我们定义了实体的属性。我们有id字段,用于使用@PrimaryGeneratedColumn()装饰器为数据库中的每条记录生成随机id;name字段用于存储将使用@Column装饰器上载的图像的名称;dateCreated和dateUpdate字段用于保存记录创建和更新的日期,使用@CreateDateColumn()。

创建上传服务

创建映像实体后,让我们创建一个服务来执行CRUD操作以处理文件上传。在app.service.ts文件中,添加下面的代码段。

TypeScript
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Image } from './image.entity';
​
@Injectable()
export class AppService {
  constructor(
    @InjectRepository(Image)
    private readonly imageRepository: Repository<Image>,
  ) {}
​
  async getImages(): Promise<Image[]> {
    return this.imageRepository.find();
  }
​
  async createImage(image: Image): Promise<Image> {
    return this.imageRepository.save(image);
  }
​
  async getImage(id: number): Promise<Image> {
    return this.imageRepository.findOneBy({ id });
  }
​
  async deleteImage(id: number): Promise<void> {
    await this.imageRepository.delete(id);
  }
}

在上面的代码段中,我们导入了injectRepository装饰器以将ImageRepositorie注入AppService和存储库,它为您提供了对数据库执行某些操作所需的方法。因此,对于createImage图像服务,我们保存上传的图像的名称,该名称将通过控制器传递。

创建上传控制器

现在,让我们创建控制器来使用这些服务。在app.controller.ts文件并添加下面的代码段。

TypeScript
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Image } from './image.entity';
​
@Injectable()
export class AppService {
  constructor(
    @InjectRepository(Image)
    private readonly imageRepository: Repository<Image>,
  ) {}
​
  async getImages(): Promise<Image[]> {
    return this.imageRepository.find();
  }
​
  async createImage(image: Image): Promise<Image> {
    return this.imageRepository.save(image);
  }
​
  async getImage(id: number): Promise<Image> {
    return this.imageRepository.findOneBy({ id });
  }
​
  async deleteImage(id: number): Promise<void> {
    await this.imageRepository.delete(id);
  }
}

在上面的代码段中,我们导入了两个装饰器,如FileInterceptor、UploadedFile和UseInterceptors。路由处理程序的FileInterceptor()拦截器使用@UploadedFile()装饰器从请求中提取文件。FileInterceptor()修饰符是从@nestjs/platform express包导出的。@UploadedFile()修饰符是从@nestjs/common导出的。FileInterceptor()decorator接受两个参数,fieldName是从保存文件的HTML表单中提供字段名称的字符串,options是MulterOptions类型的可选对象。这与multer构造函数使用的对象相同。
关于createImage函数,我们使用上述修饰符处理文件上传,使用FileInterceptor()传递图像的字段名,并修改FileIntercept()函数,通过使用multer中可用的diskStorage函数指定存储属性将图像上传到磁盘。然后我们指定图像的位置,并为图像生成随机名称。此外,我们还添加了一个过滤器属性来限制某些图像格式的上传。现在,我们使用@UploadedFile()修饰符提取文件,获取名称并将其保存到数据库中。这样,我们可以使用每个图像的名称从存储位置获取图像。
要使上述代码正常工作,您需要在终端中运行以下命令来安装multer:

Shell
npm i -D @types/multer

然后,您需要在app.module.ts file的导入数组中注册multer模块:

TypeScript
...
import { MulterModule } from '@nestjs/platform-express';
​
​
@Module({
  ...
  MulterModule.register({
    dest: './files',
  }),],
  ...

上面的配置告诉multer处理文件上传和上传位置。最后但并非最不重要的是,我们应该在src目录中创建一个files文件夹来实际存储文件。

提供文件

要将应用程序中上传的图像实际提供给用户,需要通过运行下面的命令安装serve静态模块。

Shell
npm install --save @nestjs/serve-static 

然后,在app.module.ts文件的导入数组中注册ServeStaticModule,包含以下代码段:

TypeScript
...
import { ServeStaticModule } from '@nestjs/serve-static';
import { join } from 'path';
​
@Module({
  ...
  ServeStaticModule.forRoot({
    rootPath: join(__dirname, '..', 'files')
  }),],
  ...

在上面的代码段中,您指定了文件所在的位置以及可以从中提供服务的位置。

测试API

现在打开Postman,通过向端点localhost:4000/images发送POST请求来测试应用程序,并将有效负载作为表单数据传入请求体。
1.png
如果您现在查看文件文件夹,您应该会看到已上载的文件。您可以随意选择:也可以尝试其他路线。

结论

通过本教程,您了解了如何使用NestJS和MySQL处理文件上传。您已经学习了如何使用TypeORM连接到MySQL数据库,还创建了一个实体并将图像上传到NestJS应用程序
为了进一步阅读,您还可以阅读更多关于在NestJS中上传文件的内容。对于额外的挑战,请尝试通过保护删除和更新路由来扩展应用程序。你下一步要做什么?

原文标题:使用NestJS和MySQL处理文件上传
原文作者:Clara Ekekenta
原文链接:https://dzone.com/articles/handling-file-uploads-with-nestjs-and-mysql

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论