阅读 142

NestJS 搭建博客系统(三)— 使用TypeORM+Mysql实现数据持久化

前言

这一节我们使用 TypeORM + Mysql 实现数据持久化。

TypeORM 是一个 ORM 框架,它可以运行在 NodeJS、Browser、Cordova、PhoneGap、Ionic、React Native、Expo 和 Electron 平台上,可以与 TypeScript 和 JavaScript (ES5,ES6,ES7,ES8)一起使用。 它的目标是始终支持最新的 JavaScript 特性并提供额外的特性以帮助你开发任何使用数据库的(不管是只有几张表的小型应用还是拥有多数据库的大型企业应用)应用程序。

你也可以选择 Squelize ORM

环境配置

安装 Mysql

这里我不详细展开 Mysql 的安装方法。顺便安利个简便的配置方式,同时也是我正在使用的方式。使用 docker 运行 mysql。 github.com/huihuipan/e… 这个库里面配置了 Mysql、Mongodb、Redis、nginx、jenkins、yapi 等服务,可以根据自己需要选择自己的服务。

软件部分

软件会用到数据库工具,如 navicat / dbeaver 调试请求会用到 postman 或者也可以使用上面的 environment 里面提供的 yapi

编写代码

安装依赖

使用 TypeORM 和 mysql 需要在项目中安装以下包

npm install --save @nestjs/typeorm typeorm mysql2 复制代码

引用配置

首先我们在 app.module 中引用 TypeOrmModule,TypeOrmModule 由 @nestjs/typeorm 提供

// src/app.modules.ts import { Module } from '@nestjs/common'; import { AppController } from './app.controller'; import { AppService } from './app.service'; import { ArticleModule } from './modules/article/article.module'; import { TypeOrmModule } from '@nestjs/typeorm' @Module({   imports: [     // 使用 TypeORM 配置数据库     TypeOrmModule.forRoot({       type: 'mysql',       host: 'localhost',       port: 3306,       username: 'root',       password: '888888',       database: 'test',       entities: ["dist/modules/**/*.entity{.ts,.js}"],       synchronize: true,     }),     ArticleModule   ],   controllers: [AppController],   providers: [AppService], }) export class AppModule {} 复制代码

创建实体 Entity

Entity 是由 @Entity 装饰器装饰的模型。 TypeORM 会为此类模型创建数据库表。

新建文件 src/modules/article/entity/article.entity.ts

// src/modules/article/entity/article.entity.ts import {    Entity,    Column,    PrimaryGeneratedColumn,    UpdateDateColumn,   CreateDateColumn,   VersionColumn, } from 'typeorm'; @Entity() export class Article {     // 主键id     @PrimaryGeneratedColumn()     id: number;        // 创建时间     @CreateDateColumn()     createTime: Date        // 更新时间     @UpdateDateColumn()     updateTime: Date        // 软删除     @Column({       default: false     })     isDelete: boolean        // 更新次数     @VersionColumn()     version: number        // 文章标题     @Column('text')     title: string;     // 文章描述     @Column('text')     description: string;     // 文章内容     @Column('text')     content: string; } 复制代码

使用 DTO

关于 DTO,NestJS 是这么说的

DTO(数据传输对象)模式。DTO是一个对象,它定义了如何通过网络发送数据。我们可以通过使用 TypeScript 接口(Interface)或简单的类(Class)来定义 DTO 模式。有趣的是,我们在这里推荐使用类。为什么?类是 JavaScript ES6 标准的一部分,因此它们在编译后的 JavaScript 中被保留为实际实体。另一方面,由于 TypeScript 接口在转换过程中被删除,所以 Nest 不能在运行时引用它们。这一点很重要,因为诸如管道(Pipe)之类的特性为在运行时访问变量的元类型提供更多的可能性。

在 java 里面

DTO: 数据传输对象,原先是为分布式提供粗粒度的数据实体,减少调用次数来提升性能和降低网络压力。

简单来说,就是定义一个数据,作用类似于定义方法的入参,而且还能方便我们做其他事情。比如我们的表单验证就可以在 DTO 中使用。

创建以下文件

// src/modules/article/dto/list.dto.ts export class ListDTO {   readonly page: number;   readonly pageSize: number; } 复制代码

// src/modules/article/dto/id.dto.ts export class IdDTO {   readonly id: number } 复制代码

// src/modules/article/dto/article-create.dto.ts export class ArticleCreateDTO {   readonly title: string;   readonly description: string;   readonly content: string; } 复制代码

// src/modules/article/dto/article-edit.dto.ts export class ArticleEditDTO {   readonly id: number;   readonly title: string;   readonly description: string;   readonly content: string; } 复制代码

控制器中使用 DTO

import {    Controller,    Body,    Query,   Get,    Post, } from '@nestjs/common'; import { ArticleService } from './article.service'; import { ArticleCreateDTO } from './dto/article-create.dto'; import { ArticleEditDTO } from './dto/article-edit.dto'; import { IdDTO } from './dto/id.dto'; import { ListDTO } from './dto/list.dto'; @Controller('article') export class ArticleController {   constructor(     private articleService: ArticleService   ) {}   @Get('list')   getMore(     @Query() listDTO: ListDTO,   ) {     return this.articleService.getMore(listDTO)   }   @Get('info')   getOne(     @Query() idDto: IdDTO   ) {     return this.articleService.getOne(idDto)   }   @Post('create')   create(     @Body() articleCreateDTO: ArticleCreateDTO   ) {     return this.articleService.create(articleCreateDTO)   }   @Post('edit')   update(     @Body() articleEditDTO: ArticleEditDTO   ) {     return this.articleService.update(articleEditDTO)   }   @Post('delete')   delete(     @Body() idDto: IdDTO,   ) {     return this.articleService.delete(idDto)   } } 复制代码

在 article.module 中定义使用那些存储库

import { Module } from '@nestjs/common'; import { ArticleService } from './article.service'; import { ArticleController } from './article.controller'; import { Article } from './entity/article.entity'; import { TypeOrmModule } from '@nestjs/typeorm'; @Module({   imports: [     TypeOrmModule.forFeature([Article]),   ],   providers: [ArticleService],   controllers: [ArticleController] }) export class ArticleModule {} 复制代码

同时修改下我们的服务,改为使用 TypeORM 存取数据

import { Injectable } from '@nestjs/common'; import { ArticleCreateDTO } from './dto/article-create.dto'; import { ArticleEditDTO } from './dto/article-edit.dto'; import { IdDTO } from './dto/id.dto'; import { ListDTO } from './dto/list.dto'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Article } from './entity/article.entity'; @Injectable() export class ArticleService {   list: any[];      constructor(     @InjectRepository(Article)     private readonly articleRepository: Repository<Article>,   ) {     this.list = []   }   async getMore(     listDTO: ListDTO,   ) {     const { page = 1, pageSize = 10 } = listDTO     const getList = this.articleRepository       .createQueryBuilder('article')       .where({ isDelete: false })       .select([         'article.id',         'article.title',          'article.description',         'article.createTime',         'article.updateTime',       ])       .skip((page - 1) * pageSize)       .take(pageSize)       .getMany()     const list = await getList     return list   }   async getOne(     idDto: IdDTO     ) {     const { id } = idDto     const articleDetial = await this.articleRepository       .createQueryBuilder('article')       .where('article.id = :id', { id })       .getOne()     return articleDetial;   }   async create(     articleCreateDTO: ArticleCreateDTO   ):Promise<Article>{     const article = new Article();     article.title = articleCreateDTO.title     article.description = articleCreateDTO.description     article.content = articleCreateDTO.content     const result = await this.articleRepository.save(article);     return result   }   async update(     articleEditDTO: ArticleEditDTO   ): Promise<Article>{     const { id } = articleEditDTO     let articleToUpdate = await this.articleRepository.findOne({ id })     articleToUpdate.title = articleEditDTO.title     articleToUpdate.description = articleEditDTO.description     articleToUpdate.content = articleEditDTO.content     const result = await this.articleRepository.save(articleToUpdate)     return result   }      async delete (     idDTO: IdDTO,   ) {     const { id } = idDTO     let articleToUpdate = await this.articleRepository.findOne({ id })     articleToUpdate.isDelete = true     const result = await this.articleRepository.save(articleToUpdate)     return result   } }


作者:斯蒂芬大狗
链接:https://juejin.cn/post/6992097780487929870


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐