使用nestjs搭建个人博客(二)—— 连接数据库

1656

记录使用nest.js搭建个人博客的一些学习分享,通过使用和笔记希望可以让自己学的更扎实,对知识点的掌握更熟练。上次已经搭建好了项目,今日就连接好数据库并通过接口修改数据。

起步

因为比较熟悉mysql数据库,所以我就在nestjs来集成mysql了,安装依赖:

npm install --save @nestjs/typeorm typeorm mysql2

通过上面的安装,我们就在nestjs集成了mysql库并使用typeorm来操作。

  • mysql2: 用于node.js来操作mysql的库;
  • typeorm:一个orm库,可以理解为把对象和表做了一个映射关系,来方便操作;
  • @nestjs/typeorm:nestjs基于typeorm的封装。

使用

使用typeorm来操作数据库之前,我们得先和本地的数据库建立起连接(可以先通过navicat测一下本地数据库是否能正常连接的),例如下图:

UC}PSZ3GW~~W6J6DDC9KEXN.png

测试成功之后,我们就可以开始在nestjs里面操作数据库了。

连接数据库

nestjs里面白连接数据库非常的简单,在app.module.ts里面插入简单的配置即可,如下:

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'password',
      database: 'myblog',
      entities: ['dist/**/*.entity{.ts,.js}'], // 路径不要改
      synchronize: true,
    })
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

这样,就配置好了mysql的数据库连接了,是不是很惊讶? 但是接下来又有一个问题了,我们怎么来使用它来操作数据呢?那接下来就得介绍实体类了,这在typeorm里面是一个很重要的概念。

实体类

实体类就是数据库表结构的一种映射,通过把每个字段映射成为对象的属性,然后以操作对象的方式来影响数据库,把操作数据库的方式从编写sql变为了调用API,更加方便了开发者。

一个最简单的实体类,应该如下:

import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from 'typeorm';
import Article from './article.entity';

@Entity({
  name: 'tag',
})
class Tag {
  @PrimaryGeneratedColumn()
  id = 0;

  @Column({
    type: 'varchar',
    length: 20,
    comment: '标签名',
  })
  title = '';

  @Column({
    type: 'varchar',
    length: 20,
    comment: '创建时间',
  })
  createTime = '';
}

export default Tag;

上面的@Entity装饰器就是表明该对象是一个由typeorm维护的实体类,每一个字段都由@Column来装饰。
了解了这些后,我们就可以开始基于nestjs来操作数据库了。

当我们定义好实体类之后,启动nestjs服务后,会自动帮我们创建对应的表。

操作Mysql

操作数据库肯定就是在service层里面写代码了,nestjs提供了Repository对象供我们来操作数据库,但是在使用之前需要先在对应的module注册,如下:

// tag.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import Tag from 'src/entity/tag.entity';
import { TagController } from './tag.controller';
import { TagService } from './tag.service';

@Module({
  imports: [TypeOrmModule.forFeature([Tag])],
  controllers: [TagController],
  providers: [TagService]
})
export class TagModule {}

通过imports来引入对应的模块,然后就可以到tag.service.ts里面编写操作mysql的代码了:

// tag.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import Tag from 'src/entity/tag.entity';
import { Repository } from 'typeorm';

@Injectable()
export class TagService {
  constructor(
    @InjectRepository(Tag)
    private readonly tagRepository: Repository<Tag>
  ) {}
  
  async find() {
    return await this.tagRepository.find();
  }
}

通过以上方式,我们就可以使用tagRepository这个定义的对象来操作数据库了。
Repository是每个实体的储存库,我们可以通过它来很方便的操作数据库,这其实就是ORM操作数据库的一个理念。

通过浏览器来调接口

完成以上步骤后,就可以实现一个简单那你get接口来查询tag表的内容,主要就是编写controllerservice类,如下:

tag.controller.ts

import { Controller, Get, Req, Res } from '@nestjs/common';
import { TagService } from './tag.service';

@Controller('tag')
export class TagController {
  constructor(private readonly tagService: TagService) {}

  @Get('/list')
  async getTagList(@Req() req, @Res() res) {
    const ret = await this.tagService.find();

    res.json({
      code: 200,
      data: ret
    });
  }
}

tag.service.ts

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import Tag from 'src/entity/tag.entity';
import { Repository } from 'typeorm';

@Injectable()
export class TagService {
  constructor(
    @InjectRepository(Tag)
    private readonly tagRepository: Repository<Tag>
  ) {}
  
  async find() {
    return await this.tagRepository.find();
  }
}

此时,如果操作没问题,访问/tag/list就可以看到下图结果了:

image.png

与数据库的数据一致,没有问题:

image.png

总结

今天,完成了使用nestjs来操作数据库,学到了一下:

  1. nest可以在app.module.tsimports里面引入mysql的配置;
  2. @Entity装饰器,实现实体类的一个关键:
    1. @Column:表示数据库的字段;
    2. @PrimaryGeneratedColumn():表示数据的自增主键字段;
  3. nestjs基于typeorm操作mysql的一个过程:
    1. app.module.ts做好配置,启动服务会自动建表;
    2. 在某个模块中,通过TypeOrmModule.forFeature引入对应实体;
    3. service里面,通过@InjectRepository注入对应的Repository对象;
    4. 使用实体对应Repository调用Api操作数据库。

今日任务完成,To be continue...