用 Nest.js 開發 API 吧 (七) - Entity


Posted by AlanSyue on 2021-01-16

上回有分享到用 TypeORM 連線到 Postgresql,因為 TypeORM 支援 Repository Design Pattern,每張 table 都會對應到一個 interface。

而在使用 TypeORM 連線資料庫,基本上會有三個步驟:

一、建立 Entity 檔案

首先第一步是為要新建的資料庫 table,新增一個 Entity 的檔案,像是上篇,我要建立跟使用者相關的 table,就建了 users.entity.ts 的檔案。檔案裡面會是所需資料的 interface。

我們需要先引入 typeorm:

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

定義 Entity 及 interface:

@Entity('users')
export class Users {

}

接下來要定義欄位型態、資料型態,以下介紹五個目前我有使用到的:

  1. 主鍵(primary key)
     @PrimaryGeneratedColumn()
     id: number;
    
  2. varchart 欄位
     @Column({
         type: 'varchar',
         length: 255,
     })
     email: string;
    
  3. boolean
     @Column({
         default: false,
     })
     is_verify: boolean;
    
  4. timestamp (create, update)

     @Column({
         type: 'timestamp',
         default: () => 'CURRENT_TIMESTAMP(6)'
     })
     created_at: Date;
    
     @Column({
         type: 'timestamp',
         default: () => 'CURRENT_TIMESTAMP(6)',
         onUpdate: 'CURRENT_TIMESTAMP(6)'
     })
     updated_at: Date;
    
  5. enum
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";

export enum gender {
    male = "male",
    female = "female",
    other = "other"    
}

@Entity('profiles')
export class Profiles {

    @PrimaryGeneratedColumn()
    id: number;

    @Column({
        type: "enum",
        enum: education,
        default: education.bachelor
    })
}

二、在 Module 註冊 Entity

上篇提到在 src/app.module.ts 去引入 TypeOrmModule,並使用 TypeOrmModule.forRoot() 去抓取 ormconfig.json 設定,由於 ormconfig.json 中會去讀取所有 Entity 資料夾,就會同時註冊所有 Entity。

另外也可以在 Module 中單獨註冊某個 Entity,舉例來說,我可以在 auth.module.ts 單獨註冊 users.entity,如以下範例:

路徑: src/module/auth.module.ts

import { Users } from '../entity/users.entity';

@Module({
    imports: [
        TypeOrmModule.forFeature([Users])
    ],
})

三、在 Service 使用 Repository

接著就是在 Service 去使用 Repository,我們用上篇的 users.entity.ts 當例子:

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

@Entity('users')
export class Users {
    @PrimaryGeneratedColumn()
    id: number;

    @Column({
        type: 'varchar',
        length: 255,
    })
    email: string;

    @Column({
        type: 'varchar',
        length: 255,        
    })
    password: string;

    @Column({
        type: 'varchar',
        length: 255,
        default: null      
    })
    token: string;

    @Column({
        default: false,
    })
    is_verify: boolean;

    @Column({
        type: 'timestamp',
        default: () => 'CURRENT_TIMESTAMP(6)'
    })
    created_at: Date;

    @Column({
        type: 'timestamp',
        default: () => 'CURRENT_TIMESTAMP(6)',
        onUpdate: 'CURRENT_TIMESTAMP(6)'
    })
    updated_at: Date;
}

以下範例程式碼會在 users.service.ts 去注入 usersRepository,並從中去取得 email 欄位相等於 XXX@alansyue.com 的資料:

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Users } from '../entity/users.entity';
import { UserDTO } from '../DTO/users/user.dto';

@Injectable()
export class UserService {
  constructor(
    // 注入 Users Entity
    @InjectRepository(Users)
    private readonly usersRepository: Repository<Users>,
  ) {}

  async getUserByEmail(email: string): Promise<UserDTO> {
    // 取出一筆 email 為 XXX@alansyue.com 的資料
    return await this.usersRepository.findOne({
      where: {
        email: "XXX@alansyue.com"
      }
    })
  }
}

小結

今天將上次較少著墨 Entity 的細節再補上,這次有提到在 Service 使用 Repository,會在下篇做 CRUD 時再多做說明,如果文章有任何錯誤或建議,歡迎告知!

NEXT:用 Nest.js 開發 API 吧 (八) - CRUD


#nestjs #Entity #repository #Design pattern #nodejs







Related Posts

OOP - 7 關於封裝

OOP - 7 關於封裝

Day 2 Review Course Outline

Day 2 Review Course Outline

《鳥哥 Linux 私房菜:基礎篇》Chapter 06 - Linux 的檔案與目錄管

《鳥哥 Linux 私房菜:基礎篇》Chapter 06 - Linux 的檔案與目錄管


Comments